diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..2420940a Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..07e72e78 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..63e90019 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/homework-java-ironlibrary.iml b/.idea/homework-java-ironlibrary.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/homework-java-ironlibrary.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..712ab9d9 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..52d39775 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 00000000..2b63946d --- /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 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/HELP.md b/HELP.md new file mode 100644 index 00000000..efcd3671 --- /dev/null +++ b/HELP.md @@ -0,0 +1,20 @@ +# Getting Started + +### Reference Documentation +For further reference, please consider the following sections: + +* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) +* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.2.3/maven-plugin/reference/html/) +* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.2.3/maven-plugin/reference/html/#build-image) +* [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.2.3/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data) +* [Spring Web](https://docs.spring.io/spring-boot/docs/3.2.3/reference/htmlsingle/index.html#web) + +### Guides +The following guides illustrate how to use some features concretely: + +* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) +* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) +* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) +* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) +* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/) + diff --git a/README.md b/README.md index df676c12..df1cedee 100644 --- a/README.md +++ b/README.md @@ -184,5 +184,5 @@ For this project, you must accomplish all of the following: - Everyone in the squad should contribute equally to the project in time and lines of code written. - All code must be reviewed before it is merged into the `master` branch. - All squad members must participate in code review. -- Every repository should have a README file with clear instructions, demo files, or any documentation needed so other teams don't have problems with the review. +- Every com.example.library.demo.repository should have a README file with clear instructions, demo files, or any documentation needed so other teams don't have problems with the review. - This is intended to be a challenging assignment. You will have to rely heavily on your teammates and independent research. Learning independently is a hallmark of a good developer and our job is to turn you into good developers. This process may be frustrating but you will learn a ton! diff --git a/mvnw b/mvnw new file mode 100755 index 00000000..135bdc93 --- /dev/null +++ b/mvnw @@ -0,0 +1,308 @@ +#!/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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# 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 + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -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 "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); 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 2>/dev/null; \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 + +# 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/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the com.example.library.demo.repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# 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. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +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 "$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 + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 00000000..95ba6f54 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,205 @@ +@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 Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@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 WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_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 WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_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('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@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 00000000..e3c87883 --- /dev/null +++ b/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.3 + + + com.example.library + demo + 0.0.1-SNAPSHOT + demo + Demo project for Spring Boot + + 17 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/com/example/library/demo/DemoApplication.java b/src/main/java/com/example/library/demo/DemoApplication.java new file mode 100644 index 00000000..3d5c206f --- /dev/null +++ b/src/main/java/com/example/library/demo/DemoApplication.java @@ -0,0 +1,30 @@ +package com.example.library.demo; + +import com.example.library.demo.model.Author; +import com.example.library.demo.model.Book; +import com.example.library.demo.repository.BookRepository; +import com.example.library.demo.service.LibraryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import javax.sound.midi.Soundbank; +import java.sql.SQLOutput; +import java.util.List; +import java.util.Optional; +import java.util.Scanner; + +@SpringBootApplication +public class DemoApplication implements CommandLineRunner { + @Autowired + Menu menu; + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + + @Override + public void run(String... args) throws Exception { + menu.executeCommand(); + } +} diff --git a/src/main/java/com/example/library/demo/Menu.java b/src/main/java/com/example/library/demo/Menu.java new file mode 100644 index 00000000..8c8c276a --- /dev/null +++ b/src/main/java/com/example/library/demo/Menu.java @@ -0,0 +1,237 @@ +package com.example.library.demo; + +import com.example.library.demo.model.Author; +import com.example.library.demo.model.Book; +import com.example.library.demo.model.Issue; +import com.example.library.demo.model.Student; +import com.example.library.demo.service.LibraryService; +import com.fasterxml.jackson.core.JsonToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cglib.core.Local; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.*; + +@Component +public class Menu { + private static final Scanner scanner = new Scanner(System.in); + @Autowired + private final LibraryService libraryService; + + public Menu(LibraryService libraryService) { + this.libraryService = libraryService; + } + + public void executeCommand() { + int choice; + try { + do { + System.out.println("IronLibrary Menu:"); + System.out.println("1. Add a book"); + System.out.println("2. Search book by title"); + System.out.println("3. Search book by category"); + System.out.println("4. Search book by Author"); + System.out.println("5. List all books along with author"); + System.out.println("6. Issue book to student"); + System.out.println("7. List books by usn"); + System.out.println("8. Exit"); + System.out.println("Enter your choice:"); + choice = scanner.nextInt(); + scanner.nextLine(); + + + switch (choice) { + case 1: + + try { + // Ask for book info + System.out.println("Enter ISBN: "); + String bookIsbn = scanner.nextLine(); + + // If book already exists, increment +1 in its quantity property + Optional bookOptional = libraryService.findBookByIsbn(bookIsbn); + if (bookOptional.isPresent()) { + bookOptional.get().setQuantity(bookOptional.get().getQuantity() + 1); + libraryService.addBook(bookOptional.get()); + System.out.println("Book with indicated ISBN already known. Successfully added to IronLibrary!"); + break; + } + + System.out.println("Enter title: "); + String bookTitle = scanner.nextLine(); + System.out.println("Enter category: "); + String bookCategory = scanner.nextLine(); + System.out.println("Enter Author name: "); + String authorName = scanner.nextLine(); + + // Create author object and save it in repository (only if it does not already exist) + Author bookAuthor; + Optional authorOptional = libraryService.findAuthorByName(authorName); + if (!authorOptional.isPresent()) { + System.out.println("Enter Author email: "); + String authorEmail = scanner.nextLine(); + bookAuthor = new Author(authorName, authorEmail); + libraryService.addAuthor(bookAuthor); + } else { + System.out.println("Author information already in the system!"); + bookAuthor = authorOptional.get(); + } + + System.out.println("Enter number of books: "); + int bookQuantity = scanner.nextInt(); + + + // Add book to the repository + Book newBook = new Book(bookIsbn, bookTitle, bookCategory, bookQuantity, bookAuthor); + libraryService.addBook(newBook); + + System.out.println("New book successfully added to IronLibrary!"); + + } catch (Exception e) { + System.out.println("ISBN needs to be a String"); + System.out.println(e.getMessage()); + } + + break; + case 2: + System.out.println("Enter the title of the book to search: "); + String bookTitleSearch = scanner.nextLine(); + Optional> optionalBookList = libraryService.findAllBooksByTitle(bookTitleSearch); + if (!optionalBookList.get().isEmpty()) { + List bookList = optionalBookList.get(); + System.out.println("Book(s) found! Displaying info: "); + System.out.println("ISBN Title Category Num of books Author name Author email"); + for (Book book : bookList) { + book.printBookInfo(); + } + } else { + System.out.println("Book with title " + bookTitleSearch + " not found."); + } + break; + case 3: + System.out.println("Enter the category of books to search: "); + String bookCategorySearch = scanner.nextLine(); + Optional> optionalBookList2 = libraryService.findAllBooksByCategory(bookCategorySearch); + if (optionalBookList2.isPresent()) { + List bookList = optionalBookList2.get(); + System.out.println("Book(s) found! Displaying info: "); + System.out.println("ISBN Title Category Num of books Author name Author email"); + for (Book book : bookList) { + book.printBookInfo(); + } + } else { + System.out.println("No books found for category " + bookCategorySearch); + } + break; + case 4: + System.out.println("Enter author name to display their books: "); + String authorNameSearch = scanner.nextLine(); + Optional authorOptional1 = libraryService.findAuthorByName(authorNameSearch); + if (authorOptional1.isPresent()) { + List bookList1 = libraryService.findBooksByAuthor(authorOptional1.get()); + System.out.println(authorNameSearch + "'s books found! Displaying info: "); + System.out.println("ISBN Title Category Num of books Author name Author email"); + for (Book book : bookList1) { + book.printBookInfo(); + } + } else { + System.out.println("Author with name " + authorNameSearch + "not found."); + } + + break; + case 5: + List allBooks = libraryService.listAllBooks(); + if (allBooks.isEmpty()) { + System.out.println("No books found."); + } else { + System.out.println("Books list: "); + System.out.println("ISBN Title Category Num of books Author name Author email"); + + for (Book book : allBooks) { + book.printBookInfo(); + } + } + + break; + case 6: + // Call issueBookToStudent method + // Ask for student usn and check if already exists + System.out.println("Enter student usn: "); + String studentUsn = scanner.nextLine(); + + Student student; + Optional studentOptional = libraryService.findStudentByUsn(studentUsn); + if (!studentOptional.isPresent()) { + System.out.println("Enter student name: "); + String studentName = scanner.nextLine(); + student = new Student(studentName); + libraryService.addStudent(student); + System.out.println("New student added to the system!"); + } else { + System.out.println("Student already in the system!"); + student = studentOptional.get(); + } + + // Ask for book to issue + System.out.println("Enter book ISBN to issue: "); + String bookIsbnIssue = scanner.nextLine(); + Optional optionalBook = libraryService.findBookByIsbn(bookIsbnIssue); + if (optionalBook.isPresent()) { + Book bookIssue = optionalBook.get(); + if (bookIssue.getQuantity() > 0) { + LocalDateTime todayDate = LocalDateTime.now(); + LocalDateTime returnDate = todayDate.plusDays(7); + Issue issue = new Issue(todayDate, returnDate, student, bookIssue); + libraryService.addIssue(issue); + student.addIssue(issue); + bookIssue.setQuantity(bookIssue.getQuantity() - 1); + libraryService.addBook(bookIssue); + System.out.println("Book " + bookIssue.getTitle() + " issued to " + student.getName() + ". Return date: " + returnDate); + } else { + System.out.println("Sorry. The book with ISBN " + bookIsbnIssue + " (titled " + bookIssue.getTitle() + ") is not currently available."); + } + } else { + System.out.println("Book with ISBN " + bookIsbnIssue + " not found."); + } + break; + case 7: + // Ask for student usn and check if already exists + System.out.println("Enter student usn: "); + String studentUsn2 = scanner.nextLine(); + + Student student2; + Optional studentOptional2 = libraryService.findStudentByUsn(studentUsn2); + if (!studentOptional2.isPresent()) { + System.out.println("Student with usn " + studentUsn2 + " not found."); + break; + } else { + student2 = studentOptional2.get(); + List studentIssues = student2.getIssues(); + if (studentIssues.isEmpty()) { + System.out.println("Student " + student2.getName() + " has no issued books."); + } else { + System.out.println(student2.getName() + "'s issued books: "); + System.out.println("Book Title Student Name Return date"); + for (Issue issue : studentIssues) { + issue.printIssueInfo(); + } + } + } + break; + case 8: + System.out.println("Exiting program."); + break; + default: + System.out.println("Invalid choice. Please enter a valid option."); + break; + } + } while (choice > 0 & choice != 8 & scanner.next().matches("[1-8]")); // Continue until user chooses to exit + } catch (Exception e) { + System.out.println("Illegal Argument"); + choice = 1; + } + + } +} diff --git a/src/main/java/com/example/library/demo/Utils/Functions.java b/src/main/java/com/example/library/demo/Utils/Functions.java new file mode 100644 index 00000000..c9bdc0ed --- /dev/null +++ b/src/main/java/com/example/library/demo/Utils/Functions.java @@ -0,0 +1,48 @@ +package com.example.library.demo.Utils; + +import jakarta.persistence.criteria.CriteriaBuilder; + +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Functions { + private String email; + private Integer quantity; + public static boolean isValidEmail(String email) { + String regex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(email); + return matcher.matches(); + } + + public static boolean isValidQuantity(Integer quantity){ + return quantity > 0; + } + + public static String generateISBN() { + // Prefix for ISBN-13 + String prefix = "978"; + + // Generate 9 random digits + StringBuilder sb = new StringBuilder(prefix); + Random random = new Random(); + for (int i = 0; i < 9; i++) { + sb.append(random.nextInt(10)); + } + + // Calculate the check digit + int sum = 0; + for (int i = 0; i < 12; i++) { + int digit = Character.getNumericValue(sb.charAt(i)); + sum += (i % 2 == 0) ? digit : digit * 3; + } + int checkDigit = (10 - (sum % 10)) % 10; + + // Append the check digit + sb.append(checkDigit); + + return sb.toString(); + } + +} diff --git a/src/main/java/com/example/library/demo/model/Author.java b/src/main/java/com/example/library/demo/model/Author.java new file mode 100644 index 00000000..ff8f47ed --- /dev/null +++ b/src/main/java/com/example/library/demo/model/Author.java @@ -0,0 +1,76 @@ +package com.example.library.demo.model; + +import com.example.library.demo.Utils.Functions; +import jakarta.persistence.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Entity +@Table(name = "author") +public class Author { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer authorId; + @Column(name = "author_name") + private String name; + @Column(name = "author_mail") + private String email; + + @OneToMany(mappedBy = "author") + private List bookList = new ArrayList<>(); + + public Author() { + } + + public Author(String name, String email) { + setName(name); + setEmail(email); + } + + public Integer getAuthorId() { + return authorId; + } + + public void setAuthorId(Integer authorId) { + this.authorId = authorId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + // email check + if(Functions.isValidEmail(email)){ + this.email = email; + } else { + throw new IllegalArgumentException("Not a valid e-mail"); + } + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Author author = (Author) o; + return Objects.equals(authorId, author.authorId) && Objects.equals(name, author.name) && Objects.equals(email, author.email) && Objects.equals(bookList, author.bookList); + } + + @Override + public int hashCode() { + return Objects.hash(authorId, name, email, bookList); + } +} diff --git a/src/main/java/com/example/library/demo/model/Book.java b/src/main/java/com/example/library/demo/model/Book.java new file mode 100644 index 00000000..aa3e0e17 --- /dev/null +++ b/src/main/java/com/example/library/demo/model/Book.java @@ -0,0 +1,113 @@ +package com.example.library.demo.model; + +import com.example.library.demo.Utils.Functions; +import jakarta.persistence.*; + +import java.util.Objects; + +@Entity +@Table(name = "book") +public class Book { + @Id + @Column(name = "book_isbn") + private String isbn; + @Column(name = "title") + private String title; + @Column(name = "category") + private String category; + @Column(name = "quantity") + private Integer quantity; + + @ManyToOne + @JoinColumn(name = "author_id") + private Author author; + + + //Parametrized constructor + public Book(String isbn, String title, String category, Integer quantity, Author author) {; + setIsbn(isbn); + setTitle(title); + setCategory(category); + setQuantity(quantity); + setAuthor(author); + } + + public Book() { + } + + //Getters & Setters + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + if (isbn.substring(2) == "978" & (isbn.length() >= 14 | isbn.length() <= 17)) { + this.isbn = isbn; + } else {throw new IllegalArgumentException("ISBN cannot be null or empty");} + + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + if (Functions.isValidQuantity(quantity)){ + this.quantity = quantity; + } else { + throw new IllegalArgumentException("Quantity cannot be negative");} + } + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Book book = (Book) o; + return Objects.equals(isbn, book.isbn) && Objects.equals(title, book.title) && Objects.equals(category, book.category) && Objects.equals(quantity, book.quantity) && Objects.equals(author, book.author); + } + + @Override + public int hashCode() { + return Objects.hash(isbn, title, category, quantity, author); + } + + //toString + @Override + public String toString() { + return "Book{" + + "isbn='" + isbn + '\'' + + ", title='" + title + '\'' + + ", category='" + category + '\'' + + ", quantity=" + quantity + + '}'; + } + + public void printBookInfo() { + System.out.printf("%-20s %-20s %-10s %-20s %-20s\n", isbn, title, category, quantity, author.getName(), author.getEmail()); + } +} + diff --git a/src/main/java/com/example/library/demo/model/Issue.java b/src/main/java/com/example/library/demo/model/Issue.java new file mode 100644 index 00000000..c7e56c94 --- /dev/null +++ b/src/main/java/com/example/library/demo/model/Issue.java @@ -0,0 +1,80 @@ +package com.example.library.demo.model; + +import jakarta.persistence.*; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "issue") +public class Issue { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer issueId; + @Column(name = "issue_date") + private LocalDateTime issueDate; + @Column(name = "return_date") + private LocalDateTime returnDate; + + @ManyToOne + @JoinColumn(name = "student_usn", referencedColumnName = "student_usn") + private Student issueStudent; + @OneToOne + @JoinColumn(name = "book_isbn", referencedColumnName = "book_isbn") + private Book issueBook; + + + + public Issue(LocalDateTime todayDate, LocalDateTime returnDate, Student student, Book bookIssue) { + setIssueDate(todayDate); + setReturnDate(returnDate); + setIssueStudent(student); + setIssueBook(bookIssue); + } + + public Issue() { + } + + public Integer getIssueId() { + return issueId; + } + + public void setIssueId(Integer issueId) { + this.issueId = issueId; + } + + public LocalDateTime getIssueDate() { + return issueDate; + } + + public void setIssueDate(LocalDateTime issueDate) { + this.issueDate = issueDate; + } + + public LocalDateTime getReturnDate() { + return returnDate; + } + + public void setReturnDate(LocalDateTime returnDate) { + this.returnDate = returnDate; + } + + public Student getIssueStudent() { + return issueStudent; + } + + public void setIssueStudent(Student issueStudent) { + this.issueStudent = issueStudent; + } + + public Book getIssueBook() { + return issueBook; + } + + public void setIssueBook(Book issueBook) { + this.issueBook = issueBook; + } + + public void printIssueInfo() { + System.out.printf("%-20s %-20s %-15s\n", issueBook.getTitle(), issueStudent.getName(), returnDate); + } +} diff --git a/src/main/java/com/example/library/demo/model/Student.java b/src/main/java/com/example/library/demo/model/Student.java new file mode 100644 index 00000000..0e34b04d --- /dev/null +++ b/src/main/java/com/example/library/demo/model/Student.java @@ -0,0 +1,69 @@ +package com.example.library.demo.model; + +import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +@Entity +@Table(name = "student") +public class Student { + @Id + @Column(name = "student_usn") + private String usn; + @Column(name = "student_name") + private String name; + + @OneToMany(mappedBy = "issueStudent", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) + private List issues = new ArrayList<>(); + + public Student() { + } + + public Student(String name) { + setUsn(); + setName(name); + } + + public void setUsn() { + this.usn = UUID.randomUUID().toString(); + } + + public void setName(String name) { + this.name = name; + } + + public void setIssues(List issues) { + this.issues = issues; + } + + public String getUsn() { + return usn; + } + + public String getName() { + return name; + } + + public List getIssues() { + return issues; + } + + public void addIssue(Issue newIssue) { + this.issues.add(newIssue); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Student student = (Student) o; + return Objects.equals(usn, student.usn) && Objects.equals(name, student.name) && Objects.equals(issues, student.issues); + } + + @Override + public int hashCode() { + return Objects.hash(usn, name, issues); + } +} diff --git a/src/main/java/com/example/library/demo/repository/AuthorRepository.java b/src/main/java/com/example/library/demo/repository/AuthorRepository.java new file mode 100644 index 00000000..e4e0e43a --- /dev/null +++ b/src/main/java/com/example/library/demo/repository/AuthorRepository.java @@ -0,0 +1,15 @@ +package com.example.library.demo.repository; + +import com.example.library.demo.model.Author; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface AuthorRepository extends JpaRepository { + Author save(Author author); + Optional findByAuthorId(int authorId); + Optional findByName(String name); +} diff --git a/src/main/java/com/example/library/demo/repository/BookRepository.java b/src/main/java/com/example/library/demo/repository/BookRepository.java new file mode 100644 index 00000000..2448f057 --- /dev/null +++ b/src/main/java/com/example/library/demo/repository/BookRepository.java @@ -0,0 +1,33 @@ +package com.example.library.demo.repository; + +import com.example.library.demo.model.Author; +import com.example.library.demo.model.Book; +import com.example.library.demo.model.Student; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface BookRepository extends JpaRepository { + Book save(Book book); + Optional findByIsbn(String isbn); + List findAll(); + Optional> findAllByTitle(String title); + Optional> findAllByCategory(String category); + + @Query("SELECT b FROM Book b WHERE b.author.authorId= :authorId") + List findAllByAuthor(@Param("authorId") Integer authorId); + + + + /*@Query("SELECT b FROM Book b WHERE b.student.usn= :studentUsn") + List findAllByUsn(@Param("studentUsn") String studentUsn);*/ +} \ No newline at end of file diff --git a/src/main/java/com/example/library/demo/repository/IssueRepository.java b/src/main/java/com/example/library/demo/repository/IssueRepository.java new file mode 100644 index 00000000..209088e0 --- /dev/null +++ b/src/main/java/com/example/library/demo/repository/IssueRepository.java @@ -0,0 +1,13 @@ +package com.example.library.demo.repository; + +import com.example.library.demo.model.Issue; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface IssueRepository extends JpaRepository { + Issue save(Issue issue); + Optional findByIssueId(int issueId); +} diff --git a/src/main/java/com/example/library/demo/repository/StudentRepository.java b/src/main/java/com/example/library/demo/repository/StudentRepository.java new file mode 100644 index 00000000..067b262e --- /dev/null +++ b/src/main/java/com/example/library/demo/repository/StudentRepository.java @@ -0,0 +1,15 @@ +package com.example.library.demo.repository; + +import com.example.library.demo.model.Student; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface StudentRepository extends JpaRepository { + Student save(Student student); + Optional findByUsn(String usn); + Optional findByName(String name); +} diff --git a/src/main/java/com/example/library/demo/service/LibraryService.java b/src/main/java/com/example/library/demo/service/LibraryService.java new file mode 100644 index 00000000..2340d45c --- /dev/null +++ b/src/main/java/com/example/library/demo/service/LibraryService.java @@ -0,0 +1,100 @@ +package com.example.library.demo.service; + +import com.example.library.demo.model.*; +import com.example.library.demo.repository.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class LibraryService { + @Autowired + AuthorRepository authorRepository; + @Autowired + BookRepository bookRepository; + @Autowired + IssueRepository issueRepository; + @Autowired + StudentRepository studentRepository; + + public LibraryService(AuthorRepository authorRepository, BookRepository bookRepository, IssueRepository issueRepository, StudentRepository studentRepository) { + this.authorRepository = authorRepository; + this.bookRepository = bookRepository; + this.issueRepository = issueRepository; + this.studentRepository = studentRepository; + } + + // Book Repository + public void addBook (Book book) { + bookRepository.save(book); + } + + + public List listAllBooks() { + return bookRepository.findAll(); + } + + public Optional> findAllBooksByTitle(String title) { + return bookRepository.findAllByTitle(title); + } + + public Optional> findAllBooksByCategory(String category) { + return bookRepository.findAllByCategory(category); + } + + public Optional findBookByIsbn(String isbn) { + return bookRepository.findByIsbn(isbn); + } + + // Author Repository + public void addAuthor (Author author) { + authorRepository.save(author); + } + + public Optional findAuthorByAuthorId(int authorId) { + return authorRepository.findByAuthorId(authorId); + } + + public Optional findAuthorByName(String name) { + return authorRepository.findByName(name); + } + + // Student Repository + public Optional findStudentByUsn(String usn) { + return studentRepository.findByUsn(usn); + } + + public Optional findStudentByName(String name) { + return studentRepository.findByName(name); + } + + public void addStudent (Student student) { + studentRepository.save(student); + } + + public List findBooksByAuthor(Author author){ + return bookRepository.findAllByAuthor(author.getAuthorId()); + } + + /*public List findByUsn(Student student){ + return bookRepository.findAllByUsn(student.getUsn()); + }*/ + + public List findAllBooks(){ + return bookRepository.findAll(); + } + + public void addIssue(Issue issue){ + issueRepository.save(issue); + } + + public void clean(){ + studentRepository.deleteAll(); + bookRepository.deleteAll(); + issueRepository.deleteAll(); + studentRepository.deleteAll(); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..eb9094ac --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,8 @@ +spring.datasource.url=jdbc:mysql://localhost:3306/iron_library?serverTimezone=UTC +spring.datasource.username=app_user +spring.datasource.password=P@ssw0rd! +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.show-sql=true \ No newline at end of file diff --git a/src/test/java/com/example/library/demo/DemoApplicationTests.java b/src/test/java/com/example/library/demo/DemoApplicationTests.java new file mode 100644 index 00000000..1ab277a3 --- /dev/null +++ b/src/test/java/com/example/library/demo/DemoApplicationTests.java @@ -0,0 +1,21 @@ +package com.example.library.demo; + +import com.example.library.demo.model.Book; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +@SpringBootTest +class DemoApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file diff --git a/src/test/java/repository/CommandsTest45.java b/src/test/java/repository/CommandsTest45.java new file mode 100644 index 00000000..c7382eac --- /dev/null +++ b/src/test/java/repository/CommandsTest45.java @@ -0,0 +1,93 @@ +package repository; + +import com.example.library.demo.model.Author; +import com.example.library.demo.model.Book; +import com.example.library.demo.model.Issue; +import com.example.library.demo.model.Student; +import com.example.library.demo.repository.AuthorRepository; +import com.example.library.demo.repository.BookRepository; +import com.example.library.demo.repository.IssueRepository; +import com.example.library.demo.repository.StudentRepository; +import com.example.library.demo.service.LibraryService; +import org.hamcrest.core.Is; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class CommandsTest45 { + private LibraryService libraryService; + private Book book; + private Issue issue; + private Student student; + private Author author; + + @Mock + AuthorRepository authorRepository; + @Mock + BookRepository bookRepository; + @Mock + IssueRepository issueRepository; + @Mock + StudentRepository studentRepository; + + @BeforeEach + public void setUp(){ + MockitoAnnotations.openMocks(this); + author = new Author("Darwin", "darwin@email.com"); + book = new Book("978-7-7529-4912-2", "title_test", "Horror", 1, author); + student = new Student("Laura"); + issue = new Issue(LocalDateTime.now(), LocalDateTime.now().plusDays(7),student,book); + libraryService = new LibraryService(authorRepository, bookRepository, issueRepository, studentRepository); + } + + @AfterEach + public void cleanUp(){ + libraryService.clean(); + } + + @Test + public void command1(){ + + libraryService.addBook(book); + libraryService.addAuthor(author); + libraryService.addStudent(student); + libraryService.addIssue(issue); + + List books = libraryService.findAllBooks(); + + System.out.println(books); + + assertEquals(1, books.size()); + } + + @Test + public void command2(){ + Optional> test = libraryService.findAllBooksByTitle("title_test"); + assertEquals(test.stream().count(), 1); + + } + /*@Test + void findAllByTitle() { + Optional> bookOptional = bookRepository.findAllByTitle("The Notebook"); + assertEquals(1,bookOptional.get().size()); + } + + @Test + void findAllByCategory() { + Optional> bookOptional = bookRepository.findAllByCategory("Romance"); + assertEquals(1,bookOptional.get().size()); + }*/ + + + +} diff --git a/src/test/java/resources/application.properties b/src/test/java/resources/application.properties new file mode 100644 index 00000000..eb9094ac --- /dev/null +++ b/src/test/java/resources/application.properties @@ -0,0 +1,8 @@ +spring.datasource.url=jdbc:mysql://localhost:3306/iron_library?serverTimezone=UTC +spring.datasource.username=app_user +spring.datasource.password=P@ssw0rd! +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.show-sql=true \ No newline at end of file diff --git a/target/classes/application.properties b/target/classes/application.properties new file mode 100644 index 00000000..eb9094ac --- /dev/null +++ b/target/classes/application.properties @@ -0,0 +1,8 @@ +spring.datasource.url=jdbc:mysql://localhost:3306/iron_library?serverTimezone=UTC +spring.datasource.username=app_user +spring.datasource.password=P@ssw0rd! +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +spring.jpa.hibernate.ddl-auto=update + +spring.jpa.show-sql=true \ No newline at end of file diff --git a/target/classes/com/example/library/demo/DemoApplication.class b/target/classes/com/example/library/demo/DemoApplication.class new file mode 100644 index 00000000..fcf7c9ad Binary files /dev/null and b/target/classes/com/example/library/demo/DemoApplication.class differ diff --git a/target/classes/com/example/library/demo/Menu.class b/target/classes/com/example/library/demo/Menu.class new file mode 100644 index 00000000..1f9642f1 Binary files /dev/null and b/target/classes/com/example/library/demo/Menu.class differ diff --git a/target/classes/com/example/library/demo/Utils/Functions.class b/target/classes/com/example/library/demo/Utils/Functions.class new file mode 100644 index 00000000..2aa23a83 Binary files /dev/null and b/target/classes/com/example/library/demo/Utils/Functions.class differ diff --git a/target/classes/com/example/library/demo/model/Author.class b/target/classes/com/example/library/demo/model/Author.class new file mode 100644 index 00000000..c35ff20e Binary files /dev/null and b/target/classes/com/example/library/demo/model/Author.class differ diff --git a/target/classes/com/example/library/demo/model/Book.class b/target/classes/com/example/library/demo/model/Book.class new file mode 100644 index 00000000..53ff16a0 Binary files /dev/null and b/target/classes/com/example/library/demo/model/Book.class differ diff --git a/target/classes/com/example/library/demo/model/Issue.class b/target/classes/com/example/library/demo/model/Issue.class new file mode 100644 index 00000000..5ce7965d Binary files /dev/null and b/target/classes/com/example/library/demo/model/Issue.class differ diff --git a/target/classes/com/example/library/demo/model/Student.class b/target/classes/com/example/library/demo/model/Student.class new file mode 100644 index 00000000..5d4e590c Binary files /dev/null and b/target/classes/com/example/library/demo/model/Student.class differ diff --git a/target/classes/com/example/library/demo/repository/AuthorRepository.class b/target/classes/com/example/library/demo/repository/AuthorRepository.class new file mode 100644 index 00000000..8373572b Binary files /dev/null and b/target/classes/com/example/library/demo/repository/AuthorRepository.class differ diff --git a/target/classes/com/example/library/demo/repository/BookRepository.class b/target/classes/com/example/library/demo/repository/BookRepository.class new file mode 100644 index 00000000..242c32b3 Binary files /dev/null and b/target/classes/com/example/library/demo/repository/BookRepository.class differ diff --git a/target/classes/com/example/library/demo/repository/IssueRepository.class b/target/classes/com/example/library/demo/repository/IssueRepository.class new file mode 100644 index 00000000..0da95051 Binary files /dev/null and b/target/classes/com/example/library/demo/repository/IssueRepository.class differ diff --git a/target/classes/com/example/library/demo/repository/StudentRepository.class b/target/classes/com/example/library/demo/repository/StudentRepository.class new file mode 100644 index 00000000..3c3a4815 Binary files /dev/null and b/target/classes/com/example/library/demo/repository/StudentRepository.class differ diff --git a/target/classes/com/example/library/demo/service/LibraryService.class b/target/classes/com/example/library/demo/service/LibraryService.class new file mode 100644 index 00000000..94aadf4a Binary files /dev/null and b/target/classes/com/example/library/demo/service/LibraryService.class differ diff --git a/target/test-classes/com/example/library/demo/CommandsTest45.class b/target/test-classes/com/example/library/demo/CommandsTest45.class new file mode 100644 index 00000000..9cc7257a Binary files /dev/null and b/target/test-classes/com/example/library/demo/CommandsTest45.class differ diff --git a/target/test-classes/com/example/library/demo/DemoApplicationTests.class b/target/test-classes/com/example/library/demo/DemoApplicationTests.class new file mode 100644 index 00000000..a350e65c Binary files /dev/null and b/target/test-classes/com/example/library/demo/DemoApplicationTests.class differ diff --git a/target/test-classes/com/example/library/demo/repository/BookRepositoryTest.class b/target/test-classes/com/example/library/demo/repository/BookRepositoryTest.class new file mode 100644 index 00000000..74e1fa11 Binary files /dev/null and b/target/test-classes/com/example/library/demo/repository/BookRepositoryTest.class differ diff --git a/target/test-classes/repository/BookRepositoryTest.class b/target/test-classes/repository/BookRepositoryTest.class new file mode 100644 index 00000000..6aa99188 Binary files /dev/null and b/target/test-classes/repository/BookRepositoryTest.class differ