Vorbereitung Release 0.2.0

This commit is contained in:
2026-01-29 23:50:41 +01:00
parent 58f80b3e76
commit b26b5ecc9c
571 changed files with 35728 additions and 5022 deletions
+33
View File
@@ -0,0 +1,33 @@
.gradle/
.settings/
build/
bin/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
.project
.classpath
.vscode/
.idea/
*.lock
logs/
frontend/generated
frontend/index.html
package*.json
tsconfig.json
types.d.ts
node_modules/
vite.*
kontor*Db
tags*
kontorHSQLDB*
.vs/
.winget
src/main/resources/application-local.properties
src/main/resources/application-prod.properties
src/main/resources/application-*.yml
/uploaded-files/
+25
View File
@@ -0,0 +1,25 @@
# ----------------------------------------------------------------------- #
FROM gradle:9.2.1-jdk21 AS builder
WORKDIR /
COPY ./src/main/ ./src/main/
COPY ./build.gradle ./
COPY ./gradle.properties ./
COPY ./settings.gradle ./
COPY ./gradle/libs.versions.toml ./gradle/
RUN gradle build --no-daemon
# ----------------------------------------------------------------------- #
FROM alpine/java:21-jre AS run
RUN apk --no-cache add curl
RUN adduser --system appuser
USER appuser
COPY --from=builder --chown=appuser:appuser /build/libs/kontor-javalin-0.2.0-SNAPSHOT.jar app.jar
EXPOSE 8400
USER appuser
CMD ["java", "-jar", "app.jar"]
+8
View File
@@ -0,0 +1,8 @@
.PYHONY: all
all:
./gradlew build
docker:
./gradlew dockerImage
+3
View File
@@ -0,0 +1,3 @@
# kontor-spring
Kontor Anwendung mit Spring Boot und Vaadin
+44
View File
@@ -0,0 +1,44 @@
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
implementation libs.javalin // Pulling in Javalin
implementation libs.jackson // For JSON serialization of persons
implementation libs.slf4j // To see some Javalin logging
compileOnly libs.lombok
annotationProcessor libs.lombok
implementation libs.postgresql
implementation libs.hibernate
implementation libs.hibernate.validator
implementation libs.hypersistence
implementation libs.validation.api
annotationProcessor libs.hibernate.jpamodelgen
implementation libs.el
annotationProcessor libs.openapi.annotation
implementation libs.javalin.openapi
implementation libs.javalin.swagger
implementation libs.javalin.redoc
testImplementation(platform(libs.junit.bom))
testImplementation "org.junit.jupiter:junit-jupiter"
}
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'de.thpeetz.kontor.Main'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
build.dependsOn fatJar
wrapper {
gradleVersion = "9.2.1"
}
+3
View File
@@ -0,0 +1,3 @@
description='Kontor with Javalin'
version=0.2.0-SNAPSHOT
group=de.thpeetz
+40
View File
@@ -0,0 +1,40 @@
[versions]
gradle = "8.6"
#junit = "5.8.2"
junit = "5.10.3"
#slf4j = "1.7.36"
slf4j = "2.0.16"
hsqldb = "2.7.1"
sqlite = "3.25.2"
jackson = "2.16.1"
#javalin = "4.6.4"
javalin = "6.7.0"
lombok = "1.18.34"
postgresql = "42.7.3"
hibernate = "7.0.5.Final"
validation = "2.0.1.Final"
hypersistence = "3.14.1"
el = "4.0.1"
openapi = "6.7.0-3"
[libraries]
junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
slf4j = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" }
jackson = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" }
javalin = { module = "io.javalin:javalin", version.ref = "javalin" }
javalin-bundle = { module = "io.javalin:javalin-bundle", version.ref = "javalin" }
lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" }
postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql" }
hibernate = { module = "org.hibernate.orm:hibernate-core", version.ref = "hibernate" }
hibernate-jpamodelgen = { module = "org.hibernate.orm:hibernate-jpamodelgen", version.ref = "hibernate" }
hibernate-validator = { module = "org.hibernate:hibernate-validator", version.ref = "hibernate" }
validation-api = { module = "javax.validation:validation-api", version.ref = "validation" }
el = { module = "org.glassfish:jakarta.el", version.ref = "el" }
hypersistence = { module = "io.hypersistence:hypersistence-utils-hibernate-70", version.ref = "hypersistence" }
javalin-openapi = { module = "io.javalin.community.openapi:javalin-openapi-plugin", version.ref = "openapi" }
javalin-swagger = { module = "io.javalin.community.openapi:javalin-swagger-plugin", version.ref = "openapi" }
javalin-redoc = { module = "io.javalin.community.openapi:javalin-redoc-plugin", version.ref = "openapi" }
openapi-annotation = { module = "io.javalin.community.openapi:openapi-annotation-processor", version.ref = "openapi" }
Binary file not shown.
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+248
View File
@@ -0,0 +1,248 @@
#!/bin/sh
#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
+93
View File
@@ -0,0 +1,93 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+1
View File
@@ -0,0 +1 @@
rootProject.name = 'kontor-javalin'
@@ -0,0 +1,89 @@
package de.thpeetz.kontor;
import java.util.HashMap;
import java.util.LinkedList;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.thpeetz.kontor.infrastructure.AppHibernateSessionFactory;
import de.thpeetz.kontor.models.comics.Comic;
import de.thpeetz.kontor.models.media.MediaFile;
import io.javalin.Javalin;
import io.javalin.config.Key;
//import jakarta.persistence.EntityManager;
public class Main {
private static Logger logger = LoggerFactory.getLogger(Main.class);
private static short port = 8400;
// private static Key<EntityManagerFactory> emf = new
// Key<EntityManagerFactory>("entityManagerFactory");
private static Key<SessionFactory> sf = new Key<>("SessionFactory");
public static void main(String[] args) {
Javalin app = Javalin.create(config -> {
config.requestLogger.http((ctx, ms) -> {
var path = ctx.path();
if (!path.equals("/health")) {
logger.info(ctx.path());
}
});
config.appData(sf, AppHibernateSessionFactory.getSessionFactory());
});
app.get("/", ctx -> ctx.json("Ok"));
app.get("/health", ctx -> {
HashMap<String, String> status = new HashMap<>();
status.put("status", "ok");
ctx.json(status);
});
app.get("/api/v1/comics", ctx -> {
var result = new LinkedList<Comic>();
ctx.appData(sf).inStatelessTransaction(session -> {
session.createSelectionQuery("from Comic", Comic.class).getResultList().forEach(comic -> {
result.add(comic);
});
});
// var em = ctx.appData(emf).createEntityManager();
// logger.info(em.toString());
// EntityManager entityManager = ctx.attribute("entityManager");
// entityManager.createQuery("select * from Comic",
// Comic.class).getResultList().forEach(comic -> {
// result.add(comic);
// });
ctx.json(result);
});
app.get("/api/v1/media/files", ctx -> {
var result = new LinkedList<>();
// ctx.appData(sf).inStatelessTransaction(session -> {
// var files = session.createSelectionQuery("from MediaFile",
// MediaFile.class).getResultList();
// result.addAll(files);
// });
var list = ctx.appData(sf).openStatelessSession().createSelectionQuery("from MediaFile", MediaFile.class)
.getResultList();
result.addAll(list);
ctx.json(result);
});
// app.before(ctx -> {
// ctx.attribute("configuration", AppHibernateConfig.configuration());
// ctx.attribute("sessionFactory",
// AppHibernateSessionFactory.getSessionFactory());
// });
app.after(ctx -> {
// SessionFactory sessionFactory = ctx.attribute("sessionFactory");
// if (sessionFactory != null) {
// logger.info("close SessionFactory");
// sessionFactory.close();
// }
// EntityManager entityManager = ctx.attribute("entityManager");
// if (entityManager != null) {
// logger.info("close EntityManager");
// entityManager.close();
// }
});
app.start(port);
logger.info("API's alive for real :-)");
}
}
@@ -0,0 +1,17 @@
package de.thpeetz.kontor.infrastructure;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.StatelessSession;
public class AppHibernate {
public static void inTransaction(Consumer<StatelessSession> consumer) {
AppHibernateSessionFactory.getSessionFactory().inStatelessTransaction(consumer);
}
public static <R> R fromTransaction(Function<StatelessSession, R> function) {
return AppHibernateSessionFactory.getSessionFactory().fromStatelessTransaction(function);
}
}
@@ -0,0 +1,54 @@
package de.thpeetz.kontor.infrastructure;
import java.util.Properties;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.schema.Action;
import de.thpeetz.kontor.models.comics.Artist;
import de.thpeetz.kontor.models.comics.Comic;
import de.thpeetz.kontor.models.comics.ComicWork;
import de.thpeetz.kontor.models.comics.Issue;
import de.thpeetz.kontor.models.comics.IssueWork;
import de.thpeetz.kontor.models.comics.Publisher;
import de.thpeetz.kontor.models.comics.StoryArc;
import de.thpeetz.kontor.models.comics.TradePaperback;
import de.thpeetz.kontor.models.comics.Volume;
import de.thpeetz.kontor.models.comics.Worktype;
import de.thpeetz.kontor.models.media.MediaActor;
import de.thpeetz.kontor.models.media.MediaActorFile;
import de.thpeetz.kontor.models.media.MediaArticle;
import de.thpeetz.kontor.models.media.MediaFile;
import de.thpeetz.kontor.models.media.MediaVideo;
public class AppHibernateConfig {
public static Configuration configuration() {
var configuration = new Configuration();
var settings = new Properties();
settings.put(AvailableSettings.JAKARTA_JDBC_DRIVER, "org.postgresql.Driver");
settings.put(AvailableSettings.JAKARTA_JDBC_URL, "jdbc:postgresql://postgres:5432/kontor");
settings.put(AvailableSettings.JAKARTA_JDBC_USER, "kontor");
settings.put(AvailableSettings.JAKARTA_JDBC_PASSWORD, "kontor");
settings.put(AvailableSettings.HIGHLIGHT_SQL, true);
settings.put(AvailableSettings.HBM2DDL_AUTO, Action.ACTION_UPDATE);
configuration.setProperties(settings);
configuration.addAnnotatedClass(MediaFile.class);
configuration.addAnnotatedClass(MediaActorFile.class);
configuration.addAnnotatedClass(MediaActor.class);
configuration.addAnnotatedClass(MediaArticle.class);
configuration.addAnnotatedClass(MediaVideo.class);
configuration.addAnnotatedClass(Comic.class);
configuration.addAnnotatedClass(Publisher.class);
configuration.addAnnotatedClass(Artist.class);
configuration.addAnnotatedClass(ComicWork.class);
configuration.addAnnotatedClass(Issue.class);
configuration.addAnnotatedClass(IssueWork.class);
configuration.addAnnotatedClass(StoryArc.class);
configuration.addAnnotatedClass(TradePaperback.class);
configuration.addAnnotatedClass(Volume.class);
configuration.addAnnotatedClass(Worktype.class);
return configuration;
}
}
@@ -0,0 +1,33 @@
package de.thpeetz.kontor.infrastructure;
import java.util.Objects;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AppHibernateSessionFactory {
private static final Logger logger = LoggerFactory.getLogger(AppHibernateSessionFactory.class);
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (Objects.isNull(sessionFactory)) {
var configuration = AppHibernateConfig.configuration();
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.build();
try {
sessionFactory = configuration.buildSessionFactory(registry);
logger.info("SessionFactory created");
} catch (Throwable ex) {
logger.error("Failed to create session factory", ex);
StandardServiceRegistryBuilder.destroy(registry);
}
}
return sessionFactory;
}
}
@@ -0,0 +1,52 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table
@Getter
@Setter
public class Artist {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(unique = true, nullable = false)
private String name;
@Column(nullable = true)
private String weblink;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<ComicWork> comicWorks = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "artist", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<IssueWork> issueWorks = new LinkedList<>();
}
@@ -0,0 +1,93 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table
@Getter
@Setter
public class Comic {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(unique = true, nullable = false)
private String title;
@ManyToOne
@JoinColumn(name = "publisher_id", nullable = false)
@JsonIgnoreProperties({ "comics" })
private Publisher publisher;
@Column(name = "current_order")
private Boolean currentOrder = false;
private Boolean completed = false;
@Column(nullable = true)
private String weblink;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<ComicWork> comicWorks;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true)
private List<Issue> issues = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true)
private List<StoryArc> storyArcs = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true)
private List<TradePaperback> tradePaperbacks = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "comic", cascade = CascadeType.REFRESH, orphanRemoval = true)
private List<Volume> volumes = new LinkedList<>();
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Comic{");
sb.append("title='").append(title).append('\'');
sb.append(", publisher=").append(publisher);
sb.append(", currentOrder=").append(currentOrder);
sb.append(", completed=").append(completed);
sb.append('}');
return sb.toString();
}
public String getPublisherName() {
return this.publisher.getName();
}
}
@@ -0,0 +1,12 @@
package de.thpeetz.kontor.models.comics;
import java.util.List;
import org.hibernate.StatelessSession;
import org.hibernate.annotations.processing.Find;
public interface ComicQueries {
@Find
List<Comic> getAllComics(StatelessSession session);
}
@@ -0,0 +1,53 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
@Entity
@Table(name = "comic_work")
public class ComicWork {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@ManyToOne
@JoinColumn(name = "comic_id", nullable = false)
private Comic comic;
@ManyToOne
@JoinColumn(name = "artist_id", nullable = false)
private Artist artist;
@ManyToOne
@JoinColumn(name = "work_type_id", nullable = false)
private Worktype workType;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ComicWork{");
sb.append("comic=").append(comic);
sb.append(", artist=").append(artist);
sb.append(", workType=").append(workType);
sb.append('}');
return sb.toString();
}
}
@@ -0,0 +1,126 @@
package de.thpeetz.kontor.models.comics;
import java.time.YearMonth;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.hypersistence.utils.hibernate.type.basic.YearMonthDateType;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Type;
@Entity
@Table
@Getter
@Setter
public class Issue {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@ManyToOne
@JoinColumn(name = "comic_id", nullable = false)
@JsonIgnoreProperties({ "issues" })
private Comic comic;
@ManyToOne
@JoinColumn(name = "volume_id", nullable = true)
@JsonIgnoreProperties({ "issues" })
private Volume volume;
@ManyToOne
@JoinColumn(name = "story_arc_id", nullable = true)
@JsonIgnoreProperties({ "issues" })
private StoryArc storyArc;
@Column(name = "issue_number", nullable = false)
private String issueNumber;
@Column(nullable = true)
private String title;
@Type(YearMonthDateType.class)
@Column(name = "published_on", columnDefinition = "date", nullable = true)
private YearMonth publishedOn;
@Column(name = "is_read")
private Boolean isRead;
@Column(name = "in_stock")
private Boolean inStock;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "issue", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<IssueWork> issueWorks;
public String getComicTitle() {
return comic.getTitle();
}
public String getVolumeName() {
if (volume != null) {
return volume.getName();
}
return null;
}
public String getFullTitle() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(this.getComic().getTitle());
stringBuilder.append(" #");
stringBuilder.append(this.getIssueNumber());
if (this.title != null && !this.title.isEmpty()) {
stringBuilder.append(": ");
stringBuilder.append(this.title);
}
return stringBuilder.toString();
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Issue{");
result.append("comic=");
result.append(comic);
result.append(", volume=");
result.append(volume);
result.append(", storyArc=");
result.append(storyArc);
result.append(", issueNumber='");
result.append(issueNumber);
result.append(", title='");
result.append(title);
result.append(", publishedOn=");
result.append(publishedOn);
result.append(", isRead=");
result.append(isRead);
result.append(", inStock=");
result.append(inStock);
result.append("}");
return result.toString();
}
}
@@ -0,0 +1,57 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "issue_work")
@Getter
@Setter
public class IssueWork {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@ManyToOne
@JoinColumn(name = "issue_id", nullable = false)
private Issue issue;
@ManyToOne
@JoinColumn(name = "artist_id", nullable = false)
private Artist artist;
@ManyToOne
@JoinColumn(name = "work_type_id", nullable = false)
private Worktype workType;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("IssueWork{");
sb.append("issue=").append(issue);
sb.append(", artist=").append(artist);
sb.append(", workType=").append(workType);
sb.append('}');
return sb.toString();
}
}
@@ -0,0 +1,77 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table
@Getter
@Setter
public class Publisher {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(unique = true, nullable = false)
private String name;
private String weblink;
@JsonBackReference
@ManyToOne
@JoinColumn(name = "parent_publisher_id", nullable = true)
@JsonIgnoreProperties({ "comics" })
private Publisher parentCompany;
@Column(nullable = true)
@OneToMany(fetch = FetchType.LAZY, mappedBy = "parentCompany", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Publisher> imprints = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "publisher", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comic> comics = new LinkedList<>();
public String getParentCompanyName() {
if (parentCompany != null) {
return parentCompany.name;
}
return null;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Publisher{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
@@ -0,0 +1,59 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "story_arc")
@Getter
@Setter
public class StoryArc {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(nullable = false)
private String name;
@ManyToOne
@JoinColumn(name = "comic_id", nullable = false)
@JsonIgnoreProperties({ "storyArcs" })
private Comic comic;
@ManyToOne
@JoinColumn(name = "volume_id", nullable = true)
@JsonIgnoreProperties({ "storyArcs" })
private Volume volume;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "storyArc", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Issue> issues = new LinkedList<>();
}
@@ -0,0 +1,48 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "trade_paperback")
@Getter
@Setter
public class TradePaperback {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(nullable = false)
private String name;
@ManyToOne
@JoinColumn(name = "comic_id", nullable = false)
private Comic comic;
@Column
private Integer issueStart;
@Column
private Integer issueEnd;
}
@@ -0,0 +1,69 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table
@Getter
@Setter
public class Volume {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(nullable = false)
private String name;
@ManyToOne
@JoinColumn(name = "comic_id", nullable = false)
@JsonIgnoreProperties({ "volumes" })
private Comic comic;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<StoryArc> storyArcs = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Issue> issues = new LinkedList<>();
@Override
public String toString() {
StringBuilder result = new StringBuilder("Volume{");
result.append("name=");
result.append(name);
result.append("comic=Comic{title=");
result.append(comic.getTitle());
result.append("}}");
return result.toString();
}
}
@@ -0,0 +1,53 @@
package de.thpeetz.kontor.models.comics;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
@Entity
@Table
public class Worktype {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(unique = true, nullable = false)
private String name;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<ComicWork> comicWorks = new LinkedList<>();
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "workType", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<IssueWork> issueWorks = new LinkedList<>();
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Worktype{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}
@@ -0,0 +1,51 @@
package de.thpeetz.kontor.models.media;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotEmpty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "media_actor")
public class MediaActor {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@NotEmpty
@Column(unique = true)
private String name;
@Column(nullable = true)
private String url;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "media_actor", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<MediaActorFile> mediaActorFiles = new LinkedList<>();
}
@@ -0,0 +1,56 @@
package de.thpeetz.kontor.models.media;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "media_actor_file", indexes = {
@Index(columnList = "media_file_id, media_actor_id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"media_file_id", "media_actor_id" }))
public class MediaActorFile {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@ManyToOne
@JoinColumn(name = "media_file_id")
@NotNull
private MediaFile media_file;
@ManyToOne
@JoinColumn(name = "media_actor_id")
@NotNull
private MediaActor media_actor;
public String getTitle() {
return media_file.getTitle();
}
}
@@ -0,0 +1,46 @@
package de.thpeetz.kontor.models.media;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "media_article", indexes = @Index(columnList = "url"), uniqueConstraints = @UniqueConstraint(columnNames = {
"url" }))
public class MediaArticle {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date", nullable = true)
private Date lastModifiedDate;
@NotEmpty
private String url;
@Column
private boolean review;
@Column(nullable = true)
private String title;
}
@@ -0,0 +1,71 @@
package de.thpeetz.kontor.models.media;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "media_file")
public class MediaFile {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date")
private Date lastModifiedDate;
@Column(nullable = true)
private String url;
@Column
private boolean review;
@Column(name = "should_download")
private boolean shouldDownload;
@Column(nullable = true)
private String title;
@Column(name = "cloud_link", nullable = true)
private String cloudLink;
@Column(name = "file_name", nullable = true)
private String fileName;
@Column(nullable = true)
private String path;
@Column(nullable = true)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "media_file", cascade = CascadeType.REFRESH, orphanRemoval = true)
List<MediaActorFile> mediaActorFiles = new LinkedList<>();
public static MediaFile newMediaFile(String url) {
var mediaFile = new MediaFile();
mediaFile.setUrl(url);
return mediaFile;
}
}
@@ -0,0 +1,11 @@
package de.thpeetz.kontor.models.media;
import java.util.List;
import org.hibernate.annotations.processing.Find;
public interface MediaFileQueries {
@Find
List<MediaFile> getAllMediaFiles();
}
@@ -0,0 +1,57 @@
package de.thpeetz.kontor.models.media;
import java.util.Date;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import jakarta.persistence.Version;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "media_video", uniqueConstraints = { @UniqueConstraint(columnNames = { "url" }) })
public class MediaVideo {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Version
private int version;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "last_modified_date", nullable = true)
private Date lastModifiedDate;
@Column
private String url;
@Column
private boolean review;
@Column(name = "should_download")
private boolean shouldDownload;
@Column(nullable = true)
private String title;
@Column(name = "cloud_link", nullable = true)
private String cloudLink;
@Column(name = "file_name", nullable = true)
private String fileName;
@Column(nullable = true)
private String path;
}
@@ -0,0 +1,17 @@
package de.thpeetz.kontor.web;
import java.util.List;
import de.thpeetz.kontor.infrastructure.AppHibernate;
import de.thpeetz.kontor.models.comics.Comic;
import de.thpeetz.kontor.models.comics.ComicQueries_;
import de.thpeetz.kontor.web.model.ResultComic;
import io.javalin.http.Handler;
public class ComicHandler {
public static Handler listAll = (context) -> {
List<Comic> result = AppHibernate.fromTransaction(ComicQueries_::getAllComics);
context.json(new ResultComic(result));
};
}
@@ -0,0 +1,29 @@
package de.thpeetz.kontor.web;
import java.util.LinkedList;
import java.util.List;
import de.thpeetz.kontor.infrastructure.AppHibernate;
import io.javalin.http.Handler;
import io.javalin.http.HttpStatus;
import de.thpeetz.kontor.models.media.MediaFile;
import de.thpeetz.kontor.web.model.NewMediaFile;
import de.thpeetz.kontor.web.model.ResultMediaFile;
public class MediaFileHandler {
public static Handler listAll = (context) -> {
List<MediaFile> result = new LinkedList<>();
context.json(new ResultMediaFile(result));
};
public static Handler save = (context) -> {
var newMediaFile = context.bodyAsClass(NewMediaFile.class);
var result = AppHibernate.fromTransaction(session -> {
var insertedId = session.insert(MediaFile.newMediaFile(newMediaFile.url()));
return session.get(MediaFile.class, insertedId);
});
context.json(result).status(HttpStatus.CREATED);
};
}
@@ -0,0 +1,4 @@
package de.thpeetz.kontor.web.model;
public record NewMediaFile(String url) {
}
@@ -0,0 +1,8 @@
package de.thpeetz.kontor.web.model;
import java.util.List;
import de.thpeetz.kontor.models.comics.Comic;
public record ResultComic(List<Comic> comics) {
}
@@ -0,0 +1,9 @@
package de.thpeetz.kontor.web.model;
import java.util.List;
import de.thpeetz.kontor.models.media.MediaFile;
public record ResultMediaFile(List<MediaFile> mediaFiles) {
}