commit 7c998615eed920d22511a9ebfe6e715b23e8a14b Author: Bernd Heidemann Date: Mon Mar 11 12:08:46 2024 +0100 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8e0a129 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..98f48a2 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,15 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/db/nursingHome.db + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/xerial_sqlite_jdbc.xml b/.idea/libraries/xerial_sqlite_jdbc.xml new file mode 100644 index 0000000..55a9bfb --- /dev/null +++ b/.idea/libraries/xerial_sqlite_jdbc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..c82bdb6 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..d7fb0ad --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..40ca015 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar \ No newline at end of file diff --git a/db/nursingHome.db b/db/nursingHome.db new file mode 100644 index 0000000..c3696b8 Binary files /dev/null and b/db/nursingHome.db differ diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + 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 + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. 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, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0b781d5 --- /dev/null +++ b/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + de.hitec + NHPlus + 1.0-SNAPSHOT + NHPlus + + + UTF-8 + 5.10.0 + + + + + org.openjfx + javafx-controls + 20.0.1 + + + org.openjfx + javafx-fxml + 20.0.1 + + + org.controlsfx + controlsfx + 11.1.2 + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.xerial + sqlite-jdbc + 3.44.1.0 + + + org.slf4j + slf4j-api + 2.0.9 + + + + + org.slf4j + slf4j-log4j12 + 2.0.9 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 20 + 20 + + + + org.openjfx + javafx-maven-plugin + 0.0.8 + + + + default-cli + + de.hitec.nhplus/de.hitec.nhplus.Main + app + app + app + true + true + true + + + + + + + \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/Main.java b/src/main/java/de/hitec/nhplus/Main.java new file mode 100644 index 0000000..689c380 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/Main.java @@ -0,0 +1,48 @@ +package de.hitec.nhplus; + +import de.hitec.nhplus.datastorage.ConnectionBuilder; + +import javafx.application.Application; +import javafx.application.Platform; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.BorderPane; +import javafx.stage.Stage; + +import java.io.IOException; + +public class Main extends Application { + + private Stage primaryStage; + + @Override + public void start(Stage primaryStage) { + this.primaryStage = primaryStage; + mainWindow(); + } + + public void mainWindow() { + try { + FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/MainWindowView.fxml")); + BorderPane pane = loader.load(); + + Scene scene = new Scene(pane); + this.primaryStage.setTitle("NHPlus"); + this.primaryStage.setScene(scene); + this.primaryStage.setResizable(false); + this.primaryStage.show(); + + this.primaryStage.setOnCloseRequest(event -> { + ConnectionBuilder.closeConnection(); + Platform.exit(); + System.exit(0); + }); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public static void main(String[] args) { + launch(args); + } +} \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/controller/AllPatientController.java b/src/main/java/de/hitec/nhplus/controller/AllPatientController.java new file mode 100644 index 0000000..efdeb7c --- /dev/null +++ b/src/main/java/de/hitec/nhplus/controller/AllPatientController.java @@ -0,0 +1,290 @@ +package de.hitec.nhplus.controller; + +import de.hitec.nhplus.datastorage.DaoFactory; +import de.hitec.nhplus.datastorage.PatientDao; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.control.cell.TextFieldTableCell; +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.utils.DateConverter; + +import java.sql.SQLException; +import java.time.LocalDate; + + +/** + * The AllPatientController contains the entire logic of the patient view. It determines which data is displayed and how to react to events. + */ +public class AllPatientController { + + @FXML + private TableView tableView; + + @FXML + private TableColumn columnId; + + @FXML + private TableColumn columnFirstName; + + @FXML + private TableColumn columnSurname; + + @FXML + private TableColumn columnDateOfBirth; + + @FXML + private TableColumn columnCareLevel; + + @FXML + private TableColumn columnRoomNumber; + + @FXML + private TableColumn columnAssets; + + @FXML + private Button buttonDelete; + + @FXML + private Button buttonAdd; + + @FXML + private TextField textFieldSurname; + + @FXML + private TextField textFieldFirstName; + + @FXML + private TextField textFieldDateOfBirth; + + @FXML + private TextField textFieldCareLevel; + + @FXML + private TextField textFieldRoomNumber; + + @FXML + private TextField textFieldAssets; + + private final ObservableList patients = FXCollections.observableArrayList(); + private PatientDao dao; + + /** + * When initialize() gets called, all fields are already initialized. For example from the FXMLLoader + * after loading an FXML-File. At this point of the lifecycle of the Controller, the fields can be accessed and + * configured. + */ + public void initialize() { + this.readAllAndShowInTableView(); + + this.columnId.setCellValueFactory(new PropertyValueFactory<>("pid")); + + // CellValueFactory to show property values in TableView + this.columnFirstName.setCellValueFactory(new PropertyValueFactory<>("firstName")); + // CellFactory to write property values from with in the TableView + this.columnFirstName.setCellFactory(TextFieldTableCell.forTableColumn()); + + this.columnSurname.setCellValueFactory(new PropertyValueFactory<>("surname")); + this.columnSurname.setCellFactory(TextFieldTableCell.forTableColumn()); + + this.columnDateOfBirth.setCellValueFactory(new PropertyValueFactory<>("dateOfBirth")); + this.columnDateOfBirth.setCellFactory(TextFieldTableCell.forTableColumn()); + + this.columnCareLevel.setCellValueFactory(new PropertyValueFactory<>("careLevel")); + this.columnCareLevel.setCellFactory(TextFieldTableCell.forTableColumn()); + + this.columnRoomNumber.setCellValueFactory(new PropertyValueFactory<>("roomNumber")); + this.columnRoomNumber.setCellFactory(TextFieldTableCell.forTableColumn()); + + this.columnAssets.setCellValueFactory(new PropertyValueFactory<>("assets")); + this.columnAssets.setCellFactory(TextFieldTableCell.forTableColumn()); + + //Anzeigen der Daten + this.tableView.setItems(this.patients); + + this.buttonDelete.setDisable(true); + this.tableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observableValue, Patient oldPatient, Patient newPatient) {; + AllPatientController.this.buttonDelete.setDisable(newPatient == null); + } + }); + + this.buttonAdd.setDisable(true); + ChangeListener inputNewPatientListener = (observableValue, oldText, newText) -> + AllPatientController.this.buttonAdd.setDisable(!AllPatientController.this.areInputDataValid()); + this.textFieldSurname.textProperty().addListener(inputNewPatientListener); + this.textFieldFirstName.textProperty().addListener(inputNewPatientListener); + this.textFieldDateOfBirth.textProperty().addListener(inputNewPatientListener); + this.textFieldCareLevel.textProperty().addListener(inputNewPatientListener); + this.textFieldRoomNumber.textProperty().addListener(inputNewPatientListener); + this.textFieldAssets.textProperty().addListener(inputNewPatientListener); + } + + /** + * When a cell of the column with first names was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditFirstname(TableColumn.CellEditEvent event) { + event.getRowValue().setFirstName(event.getNewValue()); + this.doUpdate(event); + } + + /** + * When a cell of the column with surnames was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditSurname(TableColumn.CellEditEvent event) { + event.getRowValue().setSurname(event.getNewValue()); + this.doUpdate(event); + } + + /** + * When a cell of the column with dates of birth was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditDateOfBirth(TableColumn.CellEditEvent event) { + event.getRowValue().setDateOfBirth(event.getNewValue()); + this.doUpdate(event); + } + + /** + * When a cell of the column with care levels was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditCareLevel(TableColumn.CellEditEvent event) { + event.getRowValue().setCareLevel(event.getNewValue()); + this.doUpdate(event); + } + + /** + * When a cell of the column with room numbers was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditRoomNumber(TableColumn.CellEditEvent event){ + event.getRowValue().setRoomNumber(event.getNewValue()); + this.doUpdate(event); + } + + /** + * When a cell of the column with assets was changed, this method will be called, to persist the change. + * + * @param event Event including the changed object and the change. + */ + @FXML + public void handleOnEditAssets(TableColumn.CellEditEvent event){ + event.getRowValue().setAssets(event.getNewValue()); + this.doUpdate(event); + } + + /** + * Updates a patient by calling the method update() of {@link PatientDao}. + * + * @param event Event including the changed object and the change. + */ + private void doUpdate(TableColumn.CellEditEvent event) { + try { + this.dao.update(event.getRowValue()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + /** + * Reloads all patients to the table by clearing the list of all patients and filling it again by all persisted + * patients, delivered by {@link PatientDao}. + */ + private void readAllAndShowInTableView() { + this.patients.clear(); + this.dao = DaoFactory.getDaoFactory().createPatientDAO(); + try { + this.patients.addAll(this.dao.readAll()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + /** + * This method handles events fired by the button to delete patients. It calls {@link PatientDao} to delete the + * patient from the database and removes the object from the list, which is the data source of the + * TableView. + */ + @FXML + public void handleDelete() { + Patient selectedItem = this.tableView.getSelectionModel().getSelectedItem(); + if (selectedItem != null) { + try { + DaoFactory.getDaoFactory().createPatientDAO().deleteById(selectedItem.getPid()); + this.tableView.getItems().remove(selectedItem); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + } + + /** + * This method handles the events fired by the button to add a patient. It collects the data from the + * TextFields, creates an object of class Patient of it and passes the object to + * {@link PatientDao} to persist the data. + */ + @FXML + public void handleAdd() { + String surname = this.textFieldSurname.getText(); + String firstName = this.textFieldFirstName.getText(); + String birthday = this.textFieldDateOfBirth.getText(); + LocalDate date = DateConverter.convertStringToLocalDate(birthday); + String careLevel = this.textFieldCareLevel.getText(); + String roomNumber = this.textFieldRoomNumber.getText(); + String assets = this.textFieldAssets.getText(); + try { + this.dao.create(new Patient(firstName, surname, date, careLevel, roomNumber, assets)); + } catch (SQLException exception) { + exception.printStackTrace(); + } + readAllAndShowInTableView(); + clearTextfields(); + } + + /** + * Clears all contents from all TextFields. + */ + private void clearTextfields() { + this.textFieldFirstName.clear(); + this.textFieldSurname.clear(); + this.textFieldDateOfBirth.clear(); + this.textFieldCareLevel.clear(); + this.textFieldRoomNumber.clear(); + this.textFieldAssets.clear(); + } + + private boolean areInputDataValid() { + if (!this.textFieldDateOfBirth.getText().isBlank()) { + try { + DateConverter.convertStringToLocalDate(this.textFieldDateOfBirth.getText()); + } catch (Exception exception) { + return false; + } + } + + return !this.textFieldFirstName.getText().isBlank() && !this.textFieldSurname.getText().isBlank() && + !this.textFieldDateOfBirth.getText().isBlank() && !this.textFieldCareLevel.getText().isBlank() && + !this.textFieldRoomNumber.getText().isBlank() && !this.textFieldAssets.getText().isBlank(); + } +} diff --git a/src/main/java/de/hitec/nhplus/controller/AllTreatmentController.java b/src/main/java/de/hitec/nhplus/controller/AllTreatmentController.java new file mode 100644 index 0000000..33f4370 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/controller/AllTreatmentController.java @@ -0,0 +1,213 @@ +package de.hitec.nhplus.controller; + +import de.hitec.nhplus.Main; +import de.hitec.nhplus.datastorage.DaoFactory; +import de.hitec.nhplus.datastorage.PatientDao; +import de.hitec.nhplus.datastorage.TreatmentDao; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.control.cell.PropertyValueFactory; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.model.Treatment; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; + +public class AllTreatmentController { + + @FXML + private TableView tableView; + + @FXML + private TableColumn columnId; + + @FXML + private TableColumn columnPid; + + @FXML + private TableColumn columnDate; + + @FXML + private TableColumn columnBegin; + + @FXML + private TableColumn columnEnd; + + @FXML + private TableColumn columnDescription; + + @FXML + private ComboBox comboBoxPatientSelection; + + @FXML + private Button buttonDelete; + + private final ObservableList treatments = FXCollections.observableArrayList(); + private TreatmentDao dao; + private final ObservableList patientSelection = FXCollections.observableArrayList(); + private ArrayList patientList; + + public void initialize() { + readAllAndShowInTableView(); + comboBoxPatientSelection.setItems(patientSelection); + comboBoxPatientSelection.getSelectionModel().select(0); + + this.columnId.setCellValueFactory(new PropertyValueFactory<>("tid")); + this.columnPid.setCellValueFactory(new PropertyValueFactory<>("pid")); + this.columnDate.setCellValueFactory(new PropertyValueFactory<>("date")); + this.columnBegin.setCellValueFactory(new PropertyValueFactory<>("begin")); + this.columnEnd.setCellValueFactory(new PropertyValueFactory<>("end")); + this.columnDescription.setCellValueFactory(new PropertyValueFactory<>("description")); + this.tableView.setItems(this.treatments); + + // Disabling the button to delete treatments as long, as no treatment was selected. + this.buttonDelete.setDisable(true); + this.tableView.getSelectionModel().selectedItemProperty().addListener( + (observableValue, oldTreatment, newTreatment) -> + AllTreatmentController.this.buttonDelete.setDisable(newTreatment == null)); + + this.createComboBoxData(); + } + + public void readAllAndShowInTableView() { + this.treatments.clear(); + comboBoxPatientSelection.getSelectionModel().select(0); + this.dao = DaoFactory.getDaoFactory().createTreatmentDao(); + try { + this.treatments.addAll(dao.readAll()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + private void createComboBoxData() { + PatientDao dao = DaoFactory.getDaoFactory().createPatientDAO(); + try { + patientList = (ArrayList) dao.readAll(); + this.patientSelection.add("alle"); + for (Patient patient: patientList) { + this.patientSelection.add(patient.getSurname()); + } + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + + @FXML + public void handleComboBox() { + String selectedPatient = this.comboBoxPatientSelection.getSelectionModel().getSelectedItem(); + this.treatments.clear(); + this.dao = DaoFactory.getDaoFactory().createTreatmentDao(); + + if (selectedPatient.equals("alle")) { + try { + this.treatments.addAll(this.dao.readAll()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + Patient patient = searchInList(selectedPatient); + if (patient !=null) { + try { + this.treatments.addAll(this.dao.readTreatmentsByPid(patient.getPid())); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + } + + private Patient searchInList(String surname) { + for (Patient patient : this.patientList) { + if (patient.getSurname().equals(surname)) { + return patient; + } + } + return null; + } + + @FXML + public void handleDelete() { + int index = this.tableView.getSelectionModel().getSelectedIndex(); + Treatment t = this.treatments.remove(index); + TreatmentDao dao = DaoFactory.getDaoFactory().createTreatmentDao(); + try { + dao.deleteById(t.getTid()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + @FXML + public void handleNewTreatment() { + try{ + String selectedPatient = this.comboBoxPatientSelection.getSelectionModel().getSelectedItem(); + Patient patient = searchInList(selectedPatient); + newTreatmentWindow(patient); + } catch (NullPointerException exception){ + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Information"); + alert.setHeaderText("Patient für die Behandlung fehlt!"); + alert.setContentText("Wählen Sie über die Combobox einen Patienten aus!"); + alert.showAndWait(); + } + } + + @FXML + public void handleMouseClick() { + tableView.setOnMouseClicked(event -> { + if (event.getClickCount() == 2 && (tableView.getSelectionModel().getSelectedItem() != null)) { + int index = this.tableView.getSelectionModel().getSelectedIndex(); + Treatment treatment = this.treatments.get(index); + treatmentWindow(treatment); + } + }); + } + + public void newTreatmentWindow(Patient patient) { + try { + FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/NewTreatmentView.fxml")); + AnchorPane pane = loader.load(); + Scene scene = new Scene(pane); + + // the primary stage should stay in the background + Stage stage = new Stage(); + + NewTreatmentController controller = loader.getController(); + controller.initialize(this, stage, patient); + + stage.setScene(scene); + stage.setResizable(false); + stage.showAndWait(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public void treatmentWindow(Treatment treatment){ + try { + FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/TreatmentView.fxml")); + AnchorPane pane = loader.load(); + Scene scene = new Scene(pane); + + // the primary stage should stay in the background + Stage stage = new Stage(); + TreatmentController controller = loader.getController(); + controller.initializeController(this, stage, treatment); + + stage.setScene(scene); + stage.setResizable(false); + stage.showAndWait(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/de/hitec/nhplus/controller/MainWindowController.java b/src/main/java/de/hitec/nhplus/controller/MainWindowController.java new file mode 100644 index 0000000..d561a7e --- /dev/null +++ b/src/main/java/de/hitec/nhplus/controller/MainWindowController.java @@ -0,0 +1,35 @@ +package de.hitec.nhplus.controller; + +import de.hitec.nhplus.Main; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.layout.BorderPane; + +import java.io.IOException; + +public class MainWindowController { + + @FXML + private BorderPane mainBorderPane; + + @FXML + private void handleShowAllPatient(ActionEvent event) { + FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/AllPatientView.fxml")); + try { + mainBorderPane.setCenter(loader.load()); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + @FXML + private void handleShowAllTreatments(ActionEvent event) { + FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/AllTreatmentView.fxml")); + try { + mainBorderPane.setCenter(loader.load()); + } catch (IOException exception) { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/de/hitec/nhplus/controller/NewTreatmentController.java b/src/main/java/de/hitec/nhplus/controller/NewTreatmentController.java new file mode 100644 index 0000000..0370b40 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/controller/NewTreatmentController.java @@ -0,0 +1,122 @@ +package de.hitec.nhplus.controller; + +import de.hitec.nhplus.datastorage.DaoFactory; +import de.hitec.nhplus.datastorage.TreatmentDao; +import javafx.beans.value.ChangeListener; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.stage.Stage; +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.model.Treatment; +import de.hitec.nhplus.utils.DateConverter; +import javafx.util.StringConverter; + +import java.sql.SQLException; +import java.time.LocalDate; +import java.time.LocalTime; + +public class NewTreatmentController { + + @FXML + private Label labelFirstName; + + @FXML + private Label labelSurname; + + @FXML + private TextField textFieldBegin; + + @FXML + private TextField textFieldEnd; + + @FXML + private TextField textFieldDescription; + + @FXML + private TextArea textAreaRemarks; + + @FXML + private DatePicker datePicker; + + @FXML + private Button buttonAdd; + + private AllTreatmentController controller; + private Patient patient; + private Stage stage; + + public void initialize(AllTreatmentController controller, Stage stage, Patient patient) { + this.controller= controller; + this.patient = patient; + this.stage = stage; + + this.buttonAdd.setDisable(true); + ChangeListener inputNewPatientListener = (observableValue, oldText, newText) -> + NewTreatmentController.this.buttonAdd.setDisable(NewTreatmentController.this.areInputDataInvalid()); + this.textFieldBegin.textProperty().addListener(inputNewPatientListener); + this.textFieldEnd.textProperty().addListener(inputNewPatientListener); + this.textFieldDescription.textProperty().addListener(inputNewPatientListener); + this.textAreaRemarks.textProperty().addListener(inputNewPatientListener); + this.datePicker.valueProperty().addListener((observableValue, localDate, t1) -> NewTreatmentController.this.buttonAdd.setDisable(NewTreatmentController.this.areInputDataInvalid())); + this.datePicker.setConverter(new StringConverter<>() { + @Override + public String toString(LocalDate localDate) { + return (localDate == null) ? "" : DateConverter.convertLocalDateToString(localDate); + } + + @Override + public LocalDate fromString(String localDate) { + return DateConverter.convertStringToLocalDate(localDate); + } + }); + this.showPatientData(); + } + + private void showPatientData(){ + this.labelFirstName.setText(patient.getFirstName()); + this.labelSurname.setText(patient.getSurname()); + } + + @FXML + public void handleAdd(){ + LocalDate date = this.datePicker.getValue(); + LocalTime begin = DateConverter.convertStringToLocalTime(textFieldBegin.getText()); + LocalTime end = DateConverter.convertStringToLocalTime(textFieldEnd.getText()); + String description = textFieldDescription.getText(); + String remarks = textAreaRemarks.getText(); + Treatment treatment = new Treatment(patient.getPid(), date, begin, end, description, remarks); + createTreatment(treatment); + controller.readAllAndShowInTableView(); + stage.close(); + } + + private void createTreatment(Treatment treatment) { + TreatmentDao dao = DaoFactory.getDaoFactory().createTreatmentDao(); + try { + dao.create(treatment); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + @FXML + public void handleCancel(){ + stage.close(); + } + + private boolean areInputDataInvalid() { + if (this.textFieldBegin.getText() == null || this.textFieldEnd.getText() == null) { + return true; + } + try { + LocalTime begin = DateConverter.convertStringToLocalTime(this.textFieldBegin.getText()); + LocalTime end = DateConverter.convertStringToLocalTime(this.textFieldEnd.getText()); + if (!end.isAfter(begin)) { + return true; + } + } catch (Exception exception) { + return true; + } + return this.textFieldDescription.getText().isBlank() || this.datePicker.getValue() == null; + } +} \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/controller/TreatmentController.java b/src/main/java/de/hitec/nhplus/controller/TreatmentController.java new file mode 100644 index 0000000..a24f54a --- /dev/null +++ b/src/main/java/de/hitec/nhplus/controller/TreatmentController.java @@ -0,0 +1,93 @@ +package de.hitec.nhplus.controller; + +import de.hitec.nhplus.datastorage.DaoFactory; +import de.hitec.nhplus.datastorage.PatientDao; +import de.hitec.nhplus.datastorage.TreatmentDao; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.stage.Stage; +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.model.Treatment; +import de.hitec.nhplus.utils.DateConverter; + +import java.sql.SQLException; +import java.time.LocalDate; + +public class TreatmentController { + + @FXML + private Label labelPatientName; + + @FXML + private Label labelCareLevel; + + @FXML + private TextField textFieldBegin; + + @FXML + private TextField textFieldEnd; + + @FXML + private TextField textFieldDescription; + + @FXML + private TextArea textAreaRemarks; + + @FXML + private DatePicker datePicker; + + private AllTreatmentController controller; + private Stage stage; + private Patient patient; + private Treatment treatment; + + public void initializeController(AllTreatmentController controller, Stage stage, Treatment treatment) { + this.stage = stage; + this.controller= controller; + PatientDao pDao = DaoFactory.getDaoFactory().createPatientDAO(); + try { + this.patient = pDao.read((int) treatment.getPid()); + this.treatment = treatment; + showData(); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + private void showData(){ + this.labelPatientName.setText(patient.getSurname()+", "+patient.getFirstName()); + this.labelCareLevel.setText(patient.getCareLevel()); + LocalDate date = DateConverter.convertStringToLocalDate(treatment.getDate()); + this.datePicker.setValue(date); + this.textFieldBegin.setText(this.treatment.getBegin()); + this.textFieldEnd.setText(this.treatment.getEnd()); + this.textFieldDescription.setText(this.treatment.getDescription()); + this.textAreaRemarks.setText(this.treatment.getRemarks()); + } + + @FXML + public void handleChange(){ + this.treatment.setDate(this.datePicker.getValue().toString()); + this.treatment.setBegin(textFieldBegin.getText()); + this.treatment.setEnd(textFieldEnd.getText()); + this.treatment.setDescription(textFieldDescription.getText()); + this.treatment.setRemarks(textAreaRemarks.getText()); + doUpdate(); + controller.readAllAndShowInTableView(); + stage.close(); + } + + private void doUpdate(){ + TreatmentDao dao = DaoFactory.getDaoFactory().createTreatmentDao(); + try { + dao.update(treatment); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + @FXML + public void handleCancel(){ + stage.close(); + } +} \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/datastorage/ConnectionBuilder.java b/src/main/java/de/hitec/nhplus/datastorage/ConnectionBuilder.java new file mode 100644 index 0000000..ea22873 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/ConnectionBuilder.java @@ -0,0 +1,40 @@ +package de.hitec.nhplus.datastorage; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import org.sqlite.SQLiteConfig; + +public class ConnectionBuilder { + + private static final String DB_NAME = "nursingHome.db"; + private static final String URL = "jdbc:sqlite:db/" + DB_NAME; + + private static Connection connection; + + synchronized public static Connection getConnection() { + try { + if (ConnectionBuilder.connection == null) { + SQLiteConfig configuration = new SQLiteConfig(); + configuration.enforceForeignKeys(true); + ConnectionBuilder.connection = DriverManager.getConnection(URL, configuration.toProperties()); + } + } catch (SQLException exception) { + System.out.println("Verbindung zur Datenbank konnte nicht aufgebaut werden!"); + exception.printStackTrace(); + } + return ConnectionBuilder.connection; + } + + synchronized public static void closeConnection() { + try { + if (ConnectionBuilder.connection != null) { + ConnectionBuilder.connection.close(); + ConnectionBuilder.connection = null; + } + } catch (SQLException exception) { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/de/hitec/nhplus/datastorage/Dao.java b/src/main/java/de/hitec/nhplus/datastorage/Dao.java new file mode 100644 index 0000000..a2e0223 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/Dao.java @@ -0,0 +1,16 @@ +package de.hitec.nhplus.datastorage; + +import java.sql.SQLException; +import java.util.List; + +public interface Dao { + void create(T t) throws SQLException; + + T read(long key) throws SQLException; + + List readAll() throws SQLException; + + void update(T t) throws SQLException; + + void deleteById(long key) throws SQLException; +} diff --git a/src/main/java/de/hitec/nhplus/datastorage/DaoFactory.java b/src/main/java/de/hitec/nhplus/datastorage/DaoFactory.java new file mode 100644 index 0000000..063e29f --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/DaoFactory.java @@ -0,0 +1,24 @@ +package de.hitec.nhplus.datastorage; + +public class DaoFactory { + + private static DaoFactory instance; + + private DaoFactory() { + } + + public static DaoFactory getDaoFactory() { + if (DaoFactory.instance == null) { + DaoFactory.instance = new DaoFactory(); + } + return DaoFactory.instance; + } + + public TreatmentDao createTreatmentDao() { + return new TreatmentDao(ConnectionBuilder.getConnection()); + } + + public PatientDao createPatientDAO() { + return new PatientDao(ConnectionBuilder.getConnection()); + } +} diff --git a/src/main/java/de/hitec/nhplus/datastorage/DaoImp.java b/src/main/java/de/hitec/nhplus/datastorage/DaoImp.java new file mode 100644 index 0000000..be502bd --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/DaoImp.java @@ -0,0 +1,57 @@ +package de.hitec.nhplus.datastorage; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public abstract class DaoImp implements Dao { + protected Connection connection; + + public DaoImp(Connection connection) { + this.connection = connection; + } + + @Override + public void create(T t) throws SQLException { + getCreateStatement(t).executeUpdate(); + } + + @Override + public T read(long key) throws SQLException { + T object = null; + ResultSet result = getReadByIDStatement(key).executeQuery(); + if (result.next()) { + object = getInstanceFromResultSet(result); + } + return object; + } + + @Override + public List readAll() throws SQLException { + return getListFromResultSet(getReadAllStatement().executeQuery()); + } + + @Override + public void update(T t) throws SQLException { + getUpdateStatement(t).executeUpdate(); + } + + @Override + public void deleteById(long key) throws SQLException { + getDeleteStatement(key).executeUpdate(); + } + + protected abstract T getInstanceFromResultSet(ResultSet set) throws SQLException; + + protected abstract ArrayList getListFromResultSet(ResultSet set) throws SQLException; + + protected abstract PreparedStatement getCreateStatement(T t); + + protected abstract PreparedStatement getReadByIDStatement(long key); + + protected abstract PreparedStatement getReadAllStatement(); + + protected abstract PreparedStatement getUpdateStatement(T t); + + protected abstract PreparedStatement getDeleteStatement(long key); +} diff --git a/src/main/java/de/hitec/nhplus/datastorage/PatientDao.java b/src/main/java/de/hitec/nhplus/datastorage/PatientDao.java new file mode 100644 index 0000000..7ce270c --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/PatientDao.java @@ -0,0 +1,176 @@ +package de.hitec.nhplus.datastorage; + +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.utils.DateConverter; + +import java.sql.*; +import java.time.LocalDate; +import java.util.ArrayList; + +/** + * Implements the Interface DaoImp. Overrides methods to generate specific PreparedStatements, + * to execute the specific SQL Statements. + */ +public class PatientDao extends DaoImp { + + /** + * The constructor initiates an object of PatientDao and passes the connection to its super class. + * + * @param connection Object of Connection to execute the SQL-statements. + */ + public PatientDao(Connection connection) { + super(connection); + } + + /** + * Generates a PreparedStatement to persist the given object of Patient. + * + * @param patient Object of Patient to persist. + * @return PreparedStatement to insert the given patient. + */ + @Override + protected PreparedStatement getCreateStatement(Patient patient) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "INSERT INTO patient (firstname, surname, dateOfBirth, carelevel, roomnumber, assets) " + + "VALUES (?, ?, ?, ?, ?, ?)"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setString(1, patient.getFirstName()); + preparedStatement.setString(2, patient.getSurname()); + preparedStatement.setString(3, patient.getDateOfBirth()); + preparedStatement.setString(4, patient.getCareLevel()); + preparedStatement.setString(5, patient.getRoomNumber()); + preparedStatement.setString(6, patient.getAssets()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Generates a PreparedStatement to query a patient by a given patient id (pid). + * + * @param pid Patient id to query. + * @return PreparedStatement to query the patient. + */ + @Override + protected PreparedStatement getReadByIDStatement(long pid) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "SELECT * FROM patient WHERE pid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, pid); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Maps a ResultSet of one patient to an object of Patient. + * + * @param result ResultSet with a single row. Columns will be mapped to an object of class Patient. + * @return Object of class Patient with the data from the resultSet. + */ + @Override + protected Patient getInstanceFromResultSet(ResultSet result) throws SQLException { + return new Patient( + result.getInt(1), + result.getString(2), + result.getString(3), + DateConverter.convertStringToLocalDate(result.getString(4)), + result.getString(5), + result.getString(6), + result.getString(7)); + } + + /** + * Generates a PreparedStatement to query all patients. + * + * @return PreparedStatement to query all patients. + */ + @Override + protected PreparedStatement getReadAllStatement() { + PreparedStatement statement = null; + try { + final String SQL = "SELECT * FROM patient"; + statement = this.connection.prepareStatement(SQL); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return statement; + } + + /** + * Maps a ResultSet of all patients to an ArrayList of Patient objects. + * + * @param result ResultSet with all rows. The Columns will be mapped to objects of class Patient. + * @return ArrayList with objects of class Patient of all rows in the + * ResultSet. + */ + @Override + protected ArrayList getListFromResultSet(ResultSet result) throws SQLException { + ArrayList list = new ArrayList<>(); + while (result.next()) { + LocalDate date = DateConverter.convertStringToLocalDate(result.getString(4)); + Patient patient = new Patient(result.getInt(1), result.getString(2), + result.getString(3), date, + result.getString(5), result.getString(6), result.getString(7)); + list.add(patient); + } + return list; + } + + /** + * Generates a PreparedStatement to update the given patient, identified + * by the id of the patient (pid). + * + * @param patient Patient object to update. + * @return PreparedStatement to update the given patient. + */ + @Override + protected PreparedStatement getUpdateStatement(Patient patient) { + PreparedStatement preparedStatement = null; + try { + final String SQL = + "UPDATE patient SET " + + "firstname = ?, " + + "surname = ?, " + + "dateOfBirth = ?, " + + "carelevel = ?, " + + "roomnumber = ?, " + + "assets = ? " + + "WHERE pid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setString(1, patient.getFirstName()); + preparedStatement.setString(2, patient.getSurname()); + preparedStatement.setString(3, patient.getDateOfBirth()); + preparedStatement.setString(4, patient.getCareLevel()); + preparedStatement.setString(5, patient.getRoomNumber()); + preparedStatement.setString(6, patient.getAssets()); + preparedStatement.setLong(7, patient.getPid()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Generates a PreparedStatement to delete a patient with the given id. + * + * @param pid Id of the patient to delete. + * @return PreparedStatement to delete patient with the given id. + */ + @Override + protected PreparedStatement getDeleteStatement(long pid) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "DELETE FROM patient WHERE pid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, pid); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } +} diff --git a/src/main/java/de/hitec/nhplus/datastorage/TreatmentDao.java b/src/main/java/de/hitec/nhplus/datastorage/TreatmentDao.java new file mode 100644 index 0000000..1e0824c --- /dev/null +++ b/src/main/java/de/hitec/nhplus/datastorage/TreatmentDao.java @@ -0,0 +1,209 @@ +package de.hitec.nhplus.datastorage; + +import de.hitec.nhplus.model.Treatment; +import de.hitec.nhplus.utils.DateConverter; + +import java.sql.*; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +/** + * Implements the Interface DaoImp. Overrides methods to generate specific PreparedStatements, + * to execute the specific SQL Statements. + */ +public class TreatmentDao extends DaoImp { + + /** + * The constructor initiates an object of TreatmentDao and passes the connection to its super class. + * + * @param connection Object of Connection to execute the SQL-statements. + */ + public TreatmentDao(Connection connection) { + super(connection); + } + + /** + * Generates a PreparedStatement to persist the given object of Treatment. + * + * @param treatment Object of Treatment to persist. + * @return PreparedStatement to insert the given patient. + */ + @Override + protected PreparedStatement getCreateStatement(Treatment treatment) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "INSERT INTO treatment (pid, treatment_date, begin, end, description, remark) " + + "VALUES (?, ?, ?, ?, ?, ?)"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, treatment.getPid()); + preparedStatement.setString(2, treatment.getDate()); + preparedStatement.setString(3, treatment.getBegin()); + preparedStatement.setString(4, treatment.getEnd()); + preparedStatement.setString(5, treatment.getDescription()); + preparedStatement.setString(6, treatment.getRemarks()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Generates a PreparedStatement to query a treatment by a given treatment id (tid). + * + * @param tid Treatment id to query. + * @return PreparedStatement to query the treatment. + */ + @Override + protected PreparedStatement getReadByIDStatement(long tid) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "SELECT * FROM treatment WHERE tid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, tid); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Maps a ResultSet of one treatment to an object of Treatment. + * + * @param result ResultSet with a single row. Columns will be mapped to an object of class Treatment. + * @return Object of class Treatment with the data from the resultSet. + */ + @Override + protected Treatment getInstanceFromResultSet(ResultSet result) throws SQLException { + LocalDate date = DateConverter.convertStringToLocalDate(result.getString(3)); + LocalTime begin = DateConverter.convertStringToLocalTime(result.getString(4)); + LocalTime end = DateConverter.convertStringToLocalTime(result.getString(5)); + return new Treatment(result.getLong(1), result.getLong(2), + date, begin, end, result.getString(6), result.getString(7)); + } + + /** + * Generates a PreparedStatement to query all treatments. + * + * @return PreparedStatement to query all treatments. + */ + @Override + protected PreparedStatement getReadAllStatement() { + PreparedStatement statement = null; + try { + final String SQL = "SELECT * FROM treatment"; + statement = this.connection.prepareStatement(SQL); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return statement; + } + + /** + * Maps a ResultSet of all treatments to an ArrayList with objects of class + * Treatment. + * + * @param result ResultSet with all rows. The columns will be mapped to objects of class Treatment. + * @return ArrayList with objects of class Treatment of all rows in the + * ResultSet. + */ + @Override + protected ArrayList getListFromResultSet(ResultSet result) throws SQLException { + ArrayList list = new ArrayList(); + while (result.next()) { + LocalDate date = DateConverter.convertStringToLocalDate(result.getString(3)); + LocalTime begin = DateConverter.convertStringToLocalTime(result.getString(4)); + LocalTime end = DateConverter.convertStringToLocalTime(result.getString(5)); + Treatment treatment = new Treatment(result.getLong(1), result.getLong(2), + date, begin, end, result.getString(6), result.getString(7)); + list.add(treatment); + } + return list; + } + + /** + * Generates a PreparedStatement to query all treatments of a patient with a given patient id (pid). + * + * @param pid Patient id to query all treatments referencing this id. + * @return PreparedStatement to query all treatments of the given patient id (pid). + */ + private PreparedStatement getReadAllTreatmentsOfOnePatientByPid(long pid) { + PreparedStatement preparedStatement = null; + try { + final String SQL = "SELECT * FROM treatment WHERE pid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, pid); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Queries all treatments of a given patient id (pid) and maps the results to an ArrayList with + * objects of class Treatment. + * + * @param pid Patient id to query all treatments referencing this id. + * @return ArrayList with objects of class Treatment of all rows in the + * ResultSet. + */ + public List readTreatmentsByPid(long pid) throws SQLException { + ResultSet result = getReadAllTreatmentsOfOnePatientByPid(pid).executeQuery(); + return getListFromResultSet(result); + } + + /** + * Generates a PreparedStatement to update the given treatment, identified + * by the id of the treatment (tid). + * + * @param treatment Treatment object to update. + * @return PreparedStatement to update the given treatment. + */ + @Override + protected PreparedStatement getUpdateStatement(Treatment treatment) { + PreparedStatement preparedStatement = null; + try { + final String SQL = + "UPDATE treatment SET " + + "pid = ?, " + + "treatment_date = ?, " + + "begin = ?, " + + "end = ?, " + + "description = ?, " + + "remark = ? " + + "WHERE tid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, treatment.getPid()); + preparedStatement.setString(2, treatment.getDate()); + preparedStatement.setString(3, treatment.getBegin()); + preparedStatement.setString(4, treatment.getEnd()); + preparedStatement.setString(5, treatment.getDescription()); + preparedStatement.setString(6, treatment.getRemarks()); + preparedStatement.setLong(7, treatment.getTid()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } + + /** + * Generates a PreparedStatement to delete a treatment with the given id. + * + * @param tid Id of the Treatment to delete. + * @return PreparedStatement to delete treatment with the given id. + */ + @Override + protected PreparedStatement getDeleteStatement(long tid) { + PreparedStatement preparedStatement = null; + try { + final String SQL = + "DELETE FROM treatment WHERE tid = ?"; + preparedStatement = this.connection.prepareStatement(SQL); + preparedStatement.setLong(1, tid); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return preparedStatement; + } +} \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/model/Patient.java b/src/main/java/de/hitec/nhplus/model/Patient.java new file mode 100644 index 0000000..ffea8ce --- /dev/null +++ b/src/main/java/de/hitec/nhplus/model/Patient.java @@ -0,0 +1,148 @@ +package de.hitec.nhplus.model; + +import de.hitec.nhplus.utils.DateConverter; +import javafx.beans.property.SimpleLongProperty; +import javafx.beans.property.SimpleStringProperty; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +/** + * Patients live in a NURSING home and are treated by nurses. + */ +public class Patient extends Person { + private SimpleLongProperty pid; + private final SimpleStringProperty dateOfBirth; + private final SimpleStringProperty careLevel; + private final SimpleStringProperty roomNumber; + private final SimpleStringProperty assets; + private final List allTreatments = new ArrayList<>(); + + /** + * Constructor to initiate an object of class Patient with the given parameter. Use this constructor + * to initiate objects, which are not persisted yet, because it will not have a patient id (pid). + * + * @param firstName First name of the patient. + * @param surname Last name of the patient. + * @param dateOfBirth Date of birth of the patient. + * @param careLevel Care level of the patient. + * @param roomNumber Room number of the patient. + * @param assets Assets of the patient. + */ + public Patient(String firstName, String surname, LocalDate dateOfBirth, String careLevel, String roomNumber, String assets) { + super(firstName, surname); + this.dateOfBirth = new SimpleStringProperty(DateConverter.convertLocalDateToString(dateOfBirth)); + this.careLevel = new SimpleStringProperty(careLevel); + this.roomNumber = new SimpleStringProperty(roomNumber); + this.assets = new SimpleStringProperty(assets); + } + + /** + * Constructor to initiate an object of class Patient with the given parameter. Use this constructor + * to initiate objects, which are already persisted and have a patient id (pid). + * + * @param pid Patient id. + * @param firstName First name of the patient. + * @param surname Last name of the patient. + * @param dateOfBirth Date of birth of the patient. + * @param careLevel Care level of the patient. + * @param roomNumber Room number of the patient. + * @param assets Assets of the patient. + */ + public Patient(long pid, String firstName, String surname, LocalDate dateOfBirth, String careLevel, String roomNumber, String assets) { + super(firstName, surname); + this.pid = new SimpleLongProperty(pid); + this.dateOfBirth = new SimpleStringProperty(DateConverter.convertLocalDateToString(dateOfBirth)); + this.careLevel = new SimpleStringProperty(careLevel); + this.roomNumber = new SimpleStringProperty(roomNumber); + this.assets = new SimpleStringProperty(assets); + } + + public long getPid() { + return pid.get(); + } + + public SimpleLongProperty pidProperty() { + return pid; + } + + public String getDateOfBirth() { + return dateOfBirth.get(); + } + + public SimpleStringProperty dateOfBirthProperty() { + return dateOfBirth; + } + + /** + * Stores the given string as new birthOfDate. + * + * @param dateOfBirth as string in the following format: YYYY-MM-DD. + */ + public void setDateOfBirth(String dateOfBirth) { + this.dateOfBirth.set(dateOfBirth); + } + + public String getCareLevel() { + return careLevel.get(); + } + + public SimpleStringProperty careLevelProperty() { + return careLevel; + } + + public void setCareLevel(String careLevel) { + this.careLevel.set(careLevel); + } + + public String getRoomNumber() { + return roomNumber.get(); + } + + public SimpleStringProperty roomNumberProperty() { + return roomNumber; + } + + + public void setRoomNumber(String roomNumber) { + this.roomNumber.set(roomNumber); + } + + public String getAssets() { + return assets.get(); + } + + public SimpleStringProperty assetsProperty() { + return assets; + } + + public void setAssets(String assets) { + this.assets.set(assets); + } + + /** + * Adds a treatment to the list of treatments, if the list does not already contain the treatment. + * + * @param treatment Treatment to add. + * @return False, if the treatment was already part of the list, else true. + */ + public boolean add(Treatment treatment) { + if (this.allTreatments.contains(treatment)) { + return false; + } + this.allTreatments.add(treatment); + return true; + } + + public String toString() { + return "Patient" + "\nMNID: " + this.pid + + "\nFirstname: " + this.getFirstName() + + "\nSurname: " + this.getSurname() + + "\nBirthday: " + this.dateOfBirth + + "\nCarelevel: " + this.careLevel + + "\nRoomnumber: " + this.roomNumber + + "\nAssets: " + this.assets + + "\n"; + } +} \ No newline at end of file diff --git a/src/main/java/de/hitec/nhplus/model/Person.java b/src/main/java/de/hitec/nhplus/model/Person.java new file mode 100644 index 0000000..d7f8f9b --- /dev/null +++ b/src/main/java/de/hitec/nhplus/model/Person.java @@ -0,0 +1,37 @@ +package de.hitec.nhplus.model; + +import javafx.beans.property.SimpleStringProperty; + +public abstract class Person { + private final SimpleStringProperty firstName; + private final SimpleStringProperty surname; + + public Person(String firstName, String surname) { + this.firstName = new SimpleStringProperty(firstName); + this.surname = new SimpleStringProperty(surname); + } + + public String getFirstName() { + return firstName.get(); + } + + public SimpleStringProperty firstNameProperty() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName.set(firstName); + } + + public String getSurname() { + return surname.get(); + } + + public SimpleStringProperty surnameProperty() { + return surname; + } + + public void setSurname(String surname) { + this.surname.set(surname); + } +} diff --git a/src/main/java/de/hitec/nhplus/model/Treatment.java b/src/main/java/de/hitec/nhplus/model/Treatment.java new file mode 100644 index 0000000..e4eea2c --- /dev/null +++ b/src/main/java/de/hitec/nhplus/model/Treatment.java @@ -0,0 +1,118 @@ +package de.hitec.nhplus.model; + +import de.hitec.nhplus.utils.DateConverter; + +import java.time.LocalDate; +import java.time.LocalTime; + +public class Treatment { + private long tid; + private final long pid; + private LocalDate date; + private LocalTime begin; + private LocalTime end; + private String description; + private String remarks; + + /** + * Constructor to initiate an object of class Treatment with the given parameter. Use this constructor + * to initiate objects, which are not persisted yet, because it will not have a treatment id (tid). + * + * @param pid Id of the treated patient. + * @param date Date of the Treatment. + * @param begin Time of the start of the treatment in format "hh:MM" + * @param end Time of the end of the treatment in format "hh:MM". + * @param description Description of the treatment. + * @param remarks Remarks to the treatment. + */ + public Treatment(long pid, LocalDate date, LocalTime begin, + LocalTime end, String description, String remarks) { + this.pid = pid; + this.date = date; + this.begin = begin; + this.end = end; + this.description = description; + this.remarks = remarks; + } + + /** + * Constructor to initiate an object of class Treatment with the given parameter. Use this constructor + * to initiate objects, which are already persisted and have a treatment id (tid). + * + * @param tid Id of the treatment. + * @param pid Id of the treated patient. + * @param date Date of the Treatment. + * @param begin Time of the start of the treatment in format "hh:MM" + * @param end Time of the end of the treatment in format "hh:MM". + * @param description Description of the treatment. + * @param remarks Remarks to the treatment. + */ + public Treatment(long tid, long pid, LocalDate date, LocalTime begin, + LocalTime end, String description, String remarks) { + this.tid = tid; + this.pid = pid; + this.date = date; + this.begin = begin; + this.end = end; + this.description = description; + this.remarks = remarks; + } + + public long getTid() { + return tid; + } + + public long getPid() { + return this.pid; + } + + public String getDate() { + return date.toString(); + } + + public String getBegin() { + return begin.toString(); + } + + public String getEnd() { + return end.toString(); + } + + public void setDate(String date) { + this.date = DateConverter.convertStringToLocalDate(date); + } + + public void setBegin(String begin) { + this.begin = DateConverter.convertStringToLocalTime(begin);; + } + + public void setEnd(String end) { + this.end = DateConverter.convertStringToLocalTime(end);; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRemarks() { + return remarks; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public String toString() { + return "\nBehandlung" + "\nTID: " + this.tid + + "\nPID: " + this.pid + + "\nDate: " + this.date + + "\nBegin: " + this.begin + + "\nEnd: " + this.end + + "\nDescription: " + this.description + + "\nRemarks: " + this.remarks + "\n"; + } +} diff --git a/src/main/java/de/hitec/nhplus/utils/DateConverter.java b/src/main/java/de/hitec/nhplus/utils/DateConverter.java new file mode 100644 index 0000000..a4f43f9 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/utils/DateConverter.java @@ -0,0 +1,27 @@ +package de.hitec.nhplus.utils; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +public class DateConverter { + + private static final String DATE_FORMAT = "yyyy-MM-dd"; + private static final String TIME_FORMAT = "HH:mm"; + + public static LocalDate convertStringToLocalDate(String date) { + return LocalDate.parse(date, DateTimeFormatter.ofPattern(DATE_FORMAT)); + } + + public static LocalTime convertStringToLocalTime(String time) { + return LocalTime.parse(time, DateTimeFormatter.ofPattern(TIME_FORMAT)); + } + + public static String convertLocalDateToString(LocalDate date) { + return date.format(DateTimeFormatter.ofPattern(DATE_FORMAT)); + } + + public static String convertLocalTimeToString(LocalTime time) { + return time.format(DateTimeFormatter.ofPattern(TIME_FORMAT)); + } +} diff --git a/src/main/java/de/hitec/nhplus/utils/SetUpDB.java b/src/main/java/de/hitec/nhplus/utils/SetUpDB.java new file mode 100644 index 0000000..7596348 --- /dev/null +++ b/src/main/java/de/hitec/nhplus/utils/SetUpDB.java @@ -0,0 +1,122 @@ +package de.hitec.nhplus.utils; + +import de.hitec.nhplus.datastorage.ConnectionBuilder; +import de.hitec.nhplus.datastorage.DaoFactory; +import de.hitec.nhplus.datastorage.PatientDao; +import de.hitec.nhplus.datastorage.TreatmentDao; +import de.hitec.nhplus.model.Patient; +import de.hitec.nhplus.model.Treatment; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import static de.hitec.nhplus.utils.DateConverter.convertStringToLocalDate; +import static de.hitec.nhplus.utils.DateConverter.convertStringToLocalTime; + +/** + * Call static class provides to static methods to set up and wipe the database. It uses the class ConnectionBuilder + * and its path to build up the connection to the database. The class is executable. Executing the class will build + * up a connection to the database and calls setUpDb() to wipe the database, build up a clean database and fill the + * database with some test data. + */ +public class SetUpDB { + + /** + * This method wipes the database by dropping the tables. Then the method calls DDL statements to build it up from + * scratch and DML statements to fill the database with hard coded test data. + */ + public static void setUpDb() { + Connection connection = ConnectionBuilder.getConnection(); + SetUpDB.wipeDb(connection); + SetUpDB.setUpTablePatient(connection); + SetUpDB.setUpTableTreatment(connection); + SetUpDB.setUpPatients(); + SetUpDB.setUpTreatments(); + } + + /** + * This method wipes the database by dropping the tables. + */ + public static void wipeDb(Connection connection) { + try (Statement statement = connection.createStatement()) { + statement.execute("DROP TABLE patient"); + statement.execute("DROP TABLE treatment"); + } catch (SQLException exception) { + System.out.println(exception.getMessage()); + } + } + + private static void setUpTablePatient(Connection connection) { + final String SQL = "CREATE TABLE IF NOT EXISTS patient (" + + " pid INTEGER PRIMARY KEY AUTOINCREMENT, " + + " firstname TEXT NOT NULL, " + + " surname TEXT NOT NULL, " + + " dateOfBirth TEXT NOT NULL, " + + " carelevel TEXT NOT NULL, " + + " roomnumber TEXT NOT NULL, " + + " assets TEXt NOT NULL" + + ");"; + try (Statement statement = connection.createStatement()) { + statement.execute(SQL); + } catch (SQLException exception) { + System.out.println(exception.getMessage()); + } + } + + private static void setUpTableTreatment(Connection connection) { + final String SQL = "CREATE TABLE IF NOT EXISTS treatment (" + + " tid INTEGER PRIMARY KEY AUTOINCREMENT, " + + " pid INTEGER NOT NULL, " + + " treatment_date TEXT NOT NULL, " + + " begin TEXT NOT NULL, " + + " end TEXT NOT NULL, " + + " description TEXT NOT NULL, " + + " remark TEXT NOT NULL," + + " FOREIGN KEY (pid) REFERENCES patient (pid) ON DELETE CASCADE " + + ");"; + + try (Statement statement = connection.createStatement()) { + statement.execute(SQL); + } catch (SQLException exception) { + System.out.println(exception.getMessage()); + } + } + + + private static void setUpPatients() { + try { + PatientDao dao = DaoFactory.getDaoFactory().createPatientDAO(); + dao.create(new Patient("Seppl", "Herberger", convertStringToLocalDate("1945-12-01"), "4", "202", "vermögend")); + dao.create(new Patient("Martina", "Gerdsen", convertStringToLocalDate("1954-08-12"), "5", "010", "arm")); + dao.create(new Patient("Gertrud", "Franzen", convertStringToLocalDate("1949-04-16"), "3", "002", "normal")); + dao.create(new Patient("Ahmet", "Yilmaz", convertStringToLocalDate("1941-02-22"), "3", "013", "normal")); + dao.create(new Patient("Hans", "Neumann", convertStringToLocalDate("1955-12-12"), "2", "001", "sehr vermögend")); + dao.create(new Patient("Elisabeth", "Müller", convertStringToLocalDate("1958-03-07"), "5", "110", "arm")); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + private static void setUpTreatments() { + try { + TreatmentDao dao = DaoFactory.getDaoFactory().createTreatmentDao(); + dao.create(new Treatment(1, 1, convertStringToLocalDate("2023-06-03"), convertStringToLocalTime("11:00"), convertStringToLocalTime("15:00"), "Gespräch", "Der Patient hat enorme Angstgefühle und glaubt, er sei überfallen worden. Ihm seien alle Wertsachen gestohlen worden.\nPatient beruhigt sich erst, als alle Wertsachen im Zimmer gefunden worden sind.")); + dao.create(new Treatment(2, 1, convertStringToLocalDate("2023-06-05"), convertStringToLocalTime("11:00"), convertStringToLocalTime("12:30"), "Gespräch", "Patient irrt auf der Suche nach gestohlenen Wertsachen durch die Etage und bezichtigt andere Bewohner des Diebstahls.\nPatient wird in seinen Raum zurückbegleitet und erhält Beruhigungsmittel.")); + dao.create(new Treatment(3, 2, convertStringToLocalDate("2023-06-04"), convertStringToLocalTime("07:30"), convertStringToLocalTime("08:00"), "Waschen", "Patient mit Waschlappen gewaschen und frisch angezogen. Patient gewendet.")); + dao.create(new Treatment(4, 1, convertStringToLocalDate("2023-06-06"), convertStringToLocalTime("15:10"), convertStringToLocalTime("16:00"), "Spaziergang", "Spaziergang im Park, Patient döst im Rollstuhl ein")); + dao.create(new Treatment(8, 1, convertStringToLocalDate("2023-06-08"), convertStringToLocalTime("15:00"), convertStringToLocalTime("16:00"), "Spaziergang", "Parkspaziergang; Patient ist heute lebhafter und hat klare Momente; erzählt von seiner Tochter")); + dao.create(new Treatment(9, 2, convertStringToLocalDate("2023-06-07"), convertStringToLocalTime("11:00"), convertStringToLocalTime("11:30"), "Waschen", "Waschen per Dusche auf einem Stuhl; Patientin gewendet;")); + dao.create(new Treatment(12, 5, convertStringToLocalDate("2023-06-08"), convertStringToLocalTime("15:00"), convertStringToLocalTime("15:30"), "Physiotherapie", "Übungen zur Stabilisation und Mobilisierung der Rückenmuskulatur")); + dao.create(new Treatment(14, 4, convertStringToLocalDate("2023-08-24"), convertStringToLocalTime("09:30"), convertStringToLocalTime("10:15"), "KG", "Lympfdrainage")); + dao.create(new Treatment(16, 6, convertStringToLocalDate("2023-08-31"), convertStringToLocalTime("13:30"), convertStringToLocalTime("13:45"), "Toilettengang", "Hilfe beim Toilettengang; Patientin klagt über Schmerzen beim Stuhlgang. Gabe von Iberogast")); + dao.create(new Treatment(17, 6, convertStringToLocalDate("2023-09-01"), convertStringToLocalTime("16:00"), convertStringToLocalTime("17:00"), "KG", "Massage der Extremitäten zur Verbesserung der Durchblutung")); + } catch (SQLException exception) { + exception.printStackTrace(); + } + } + + public static void main(String[] args) { + SetUpDB.setUpDb(); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..4839e36 --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,16 @@ +module de.hitec.nhplus { + requires javafx.controls; + requires javafx.fxml; + + requires org.controlsfx.controls; + requires java.sql; + requires org.xerial.sqlitejdbc; + + opens de.hitec.nhplus to javafx.fxml; + opens de.hitec.nhplus.controller to javafx.fxml; + opens de.hitec.nhplus.model to javafx.base; + + exports de.hitec.nhplus; + exports de.hitec.nhplus.controller; + exports de.hitec.nhplus.model; +} \ No newline at end of file diff --git a/src/main/resources/de/hitec/nhplus/AllCaregiverView.fxml b/src/main/resources/de/hitec/nhplus/AllCaregiverView.fxml new file mode 100644 index 0000000..8e82ca1 --- /dev/null +++ b/src/main/resources/de/hitec/nhplus/AllCaregiverView.fxml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/de/hitec/nhplus/NewTreatmentView.fxml b/src/main/resources/de/hitec/nhplus/NewTreatmentView.fxml new file mode 100644 index 0000000..f5f8b37 --- /dev/null +++ b/src/main/resources/de/hitec/nhplus/NewTreatmentView.fxml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +