diff --git a/.editorconfig b/.editorconfig
index 8d67bc7a5..2513d2a34 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,3 +10,12 @@ indent_style = space
[*.{java,xml}]
indent_size = 4
trim_trailing_whitespace = true
+indent_style = tab
+tab_width = 4
+
+[{pom,wro}.xml]
+indent_size = 2
+indent_style = space
+
+[*.{html,sql,less}]
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index a43b14dd5..fe6a0bab1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,9 +2,17 @@ target/*
.settings/*
.classpath
.project
+.factorypath
+.attach_pid*
.idea
*.iml
/target
+.sts4-cache/
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
_site/
# Created by https://www.gitignore.io/api/ansible
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 000000000..89964d141
--- /dev/null
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0'
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if(mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if(mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if(!outputFile.getParentFile().exists()) {
+ if(!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
index c6feb8bb6..2cc7d4a55 100644
Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 25cc8af3c..2743cab67 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1 +1,3 @@
-distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
+
diff --git a/.springBeans b/.springBeans
deleted file mode 100644
index 44f18becd..000000000
--- a/.springBeans
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- 1
-
-
-
-
-
-
- src/main/resources/spring/datasource-config.xml
- src/main/resources/spring/mvc-core-config.xml
- src/main/resources/spring/mvc-view-config.xml
- src/main/resources/spring/business-config.xml
-
-
- src/main/resources/spring/tools-config.xml
-
-
-
-
diff --git a/.travis.yml b/.travis.yml
index c0f28cfa4..1e91cb501 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,2 +1,3 @@
+dist: trusty
language: java
jdk: oraclejdk8
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 000000000..559c53805
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,26 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "java",
+ "name": "Debug (Launch)-PetClinicApplication",
+ "request": "launch",
+ "cwd": "${workspaceFolder}",
+ "console": "internalConsole",
+ "stopOnEntry": false,
+ "mainClass": "org.springframework.samples.petclinic.PetClinicApplication",
+ "projectName": "spring-petclinic",
+ "args": ""
+ },
+ {
+ "type": "java",
+ "name": "Debug (Attach)",
+ "request": "attach",
+ "hostName": "localhost",
+ "port": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..c5f3f6b9c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 000000000..fabd5c416
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,19 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "verify",
+ "type": "shell",
+ "command": "mvn -B verify",
+ "group": "build"
+ },
+ {
+ "label": "test",
+ "type": "shell",
+ "command": "mvn -B test",
+ "group": "test"
+ }
+ ]
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index 1631ec9fa..5166fe90f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,9 +1,12 @@
mysql:
- image: mysql
+ image: mysql:5.7
ports:
- "3306:3306"
environment:
- - MYSQL_ROOT_PASSWORD=root
- - MYSQL_DATABASE=test
+ - MYSQL_ROOT_PASSWORD=
+ - MYSQL_ALLOW_EMPTY_PASSWORD=true
+ - MYSQL_USER=petclinic
+ - MYSQL_PASSWORD=petclinic
+ - MYSQL_DATABASE=petclinic
volumes:
- - "./conf.d:/etc/mysql/conf.d:ro"
\ No newline at end of file
+ - "./conf.d:/etc/mysql/conf.d:ro"
diff --git a/mvnw b/mvnw
index fc7efd17d..2c90d17e4 100755
--- a/mvnw
+++ b/mvnw
@@ -8,7 +8,7 @@
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 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
@@ -19,7 +19,7 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# Maven2 Start Up Batch script
+# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
@@ -54,38 +54,16 @@ case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
- #
- # Look for the Apple JDKs first to preserve the existing behaviour, and then look
- # for the new JDKs provided by Oracle.
- #
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
- #
- # Oracle JDKs
- #
- export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
- fi
-
- if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
- #
- # Apple JDKs
- #
- export JAVA_HOME=`/usr/libexec/java_home`
- fi
- ;;
+ # 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
@@ -130,13 +108,12 @@ if $cygwin ; then
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
-# For Migwn, ensure paths are in UNIX format before anything is touched
+# 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)`"
- # TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
@@ -184,27 +161,28 @@ fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-# 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"`
-fi
-
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
- local basedir=$(pwd)
- local wdir=$(pwd)
+
+ 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
- wdir=$(cd "$wdir/.."; pwd)
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
done
echo "${basedir}"
}
@@ -216,10 +194,109 @@ concat_lines() {
fi
}
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+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/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.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"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$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"
-# Provide a "standardized" way to retrieve the CLI args that will
+# 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
@@ -230,5 +307,4 @@ exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS
-
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
index 0d49a2de0..0d34af450 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -1,145 +1,182 @@
-@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 http://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 Maven2 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 key stroke 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 enable echoing my 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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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
-
-set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %*
-
-@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"
+@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 ----------------------------------------------------------------------------
-set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
-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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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%
-
-exit /B %ERROR_CODE%
+@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "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%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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%
+
+exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 776cd1a43..e4e74747a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,245 +1,384 @@
- 4.0.0
- org.springframework.samples
- spring-petclinic
- 1.5.2-SNAPSHOT
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+ org.springframework.samples
+ spring-petclinic
+ 2.3.0.BUILD-SNAPSHOT
-
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.3.RELEASE
+
+ petclinic
+
+
+
+
+ 1.8
+ UTF-8
+ UTF-8
+
+
+ 3.3.6
+ 1.11.4
+ 2.2.4
+ 1.8.0
+
+ 0.8.5
+ 0.0.4.RELEASE
+ 0.0.25
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+
+
+ javax.cache
+ cache-api
+
+
+ org.ehcache
+ ehcache
+
+
+
+
+ org.webjars
+ webjars-locator-core
+
+
+ org.webjars
+ jquery
+ ${webjars-jquery.version}
+
+
+ org.webjars
+ jquery-ui
+ ${webjars-jquery-ui.version}
+
+
+ org.webjars
+ bootstrap
+ ${webjars-bootstrap.version}
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ ${spring-format.version}
+
+
+ validate
+
+ validate
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.1.1
+
+
+ com.puppycrawl.tools
+ checkstyle
+ 8.32
+
+
+ io.spring.nohttp
+ nohttp-checkstyle
+ ${nohttp-checkstyle.version}
+
+
+
+
+ nohttp-checkstyle-validation
+ validate
+
+ src/checkstyle/nohttp-checkstyle.xml
+ src/checkstyle/nohttp-checkstyle-suppressions.xml
+ UTF-8
+ ${basedir}
+ **/*
+ **/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class
+
+
+ check
+
+
+
+
+ org.springframework.boot
- spring-boot-starter-parent
- 1.5.4.RELEASE
-
- petclinic
+ spring-boot-maven-plugin
+
+
+
+
+ build-info
+
+
+
+ ${project.build.sourceEncoding}
+ ${project.reporting.outputEncoding}
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+
+ prepare-agent
+
+
+
+ report
+ prepare-package
+
+ report
+
+
+
+
-
+
+
+ pl.project13.maven
+ git-commit-id-plugin
+
+
+
+ revision
+
+
+
+
+ true
+ yyyy-MM-dd'T'HH:mm:ssZ
+ true
+ ${project.build.outputDirectory}/git.properties
+
+ false
+
+
-
- 1.8
- UTF-8
- UTF-8
-
-
- 3.3.6
- 1.11.4
- 2.2.4
- 1.8.0
- 3.0.6.RELEASE
-
- 2.7
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
- org.springframework.boot
- spring-boot-starter-cache
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-thymeleaf
-
-
- nz.net.ultraq.thymeleaf
- thymeleaf-layout-dialect
-
-
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
-
- org.hsqldb
- hsqldb
- runtime
-
-
- mysql
- mysql-connector-java
- runtime
-
-
-
-
- javax.cache
- cache-api
-
-
- org.ehcache
- ehcache
-
-
-
-
- org.webjars
- webjars-locator
-
-
- org.webjars
- jquery
- ${webjars-jquery.version}
-
-
- org.webjars
- jquery-ui
- ${webjars-jquery-ui.version}
-
-
+
+ ro.isdc.wro4j
+ wro4j-maven-plugin
+ ${wro4j.version}
+
+
+ generate-resources
+
+ run
+
+
+
+
+ ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
+ ${project.build.directory}/classes/static/resources/css
+ ${basedir}/src/main/wro/wro.xml
+ ${basedir}/src/main/wro/wro.properties
+ ${basedir}/src/main/less
+
+
+ org.webjarsbootstrap${webjars-bootstrap.version}
-
-
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+
+
+
+
+
-
- org.springframework.boot
- spring-boot-devtools
- runtime
-
-
+
+
+ Apache License, Version 2.0
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
-
- spring-petclinic
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
- build-info
-
-
- true
-
- ${project.build.sourceEncoding}
- ${project.reporting.outputEncoding}
- ${maven.compiler.source}
- ${maven.compiler.target}
-
-
-
-
-
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
-
- org.apache.maven.plugins
- maven-failsafe-plugin
-
-
- integration-test
-
- integration-test
- verify
-
-
-
-
-
- org.codehaus.mojo
- cobertura-maven-plugin
- ${cobertura.version}
-
-
-
-
-
-
- clean
- check
-
-
-
-
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
-
+
+
+ m2e
+
+
+ m2e.version
+
+
+
+
+
+
- pl.project13.maven
- git-commit-id-plugin
-
-
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ [1,)
- revision
+ check
-
-
-
- true
- yyyy-MM-dd'T'HH:mm:ssZ
- true
- ${project.build.outputDirectory}/git.properties
-
- false
-
-
-
-
- ro.isdc.wro4j
- wro4j-maven-plugin
- ${wro4j.version}
-
-
- generate-resources
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ [1,)
- run
+ build-info
-
-
-
- ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory
-
- ${project.build.directory}/classes/static/resources/css
- ${basedir}/src/main/wro/wro.xml
- ${basedir}/src/main/wro/wro.properties
- ${basedir}/src/main/less
-
-
-
- org.webjars
- bootstrap
- ${webjars-bootstrap.version}
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
- org.codehaus.mojo
- cobertura-maven-plugin
- ${cobertura.version}
-
-
- html
-
-
-
-
-
-
+
+
+
+
+
diff --git a/readme-petclinic.md b/readme-petclinic.md
index ac30d6392..ff6d2be15 100644
--- a/readme-petclinic.md
+++ b/readme-petclinic.md
@@ -1,85 +1,102 @@
-# Spring PetClinic Sample Application [](https://travis-ci.org/spring-projects/spring-petclinic/)
+# Spring PetClinic Sample Application [](https://travis-ci.org/spring-projects/spring-petclinic/)
## Understanding the Spring Petclinic application with a few diagrams
See the presentation here
## Running petclinic locally
+Petclinic is a [Spring Boot](https://spring.io/guides/gs/spring-boot) application built using [Maven](https://spring.io/guides/gs/maven/). You can build a jar file and run it from the command line:
+
+
```
- git clone https://github.com/spring-projects/spring-petclinic.git
- cd spring-petclinic
- ./mvnw spring-boot:run
+git clone https://github.com/spring-projects/spring-petclinic.git
+cd spring-petclinic
+./mvnw package
+java -jar target/*.jar
```
You can then access petclinic here: http://localhost:8080/
+Or you can run it from Maven directly using the Spring Boot Maven plugin. If you do this it will pick up changes that you make in the project immediately (changes to Java source files require a compile as well - most people use an IDE for this):
+
+```
+./mvnw spring-boot:run
+```
+
## In case you find a bug/suggested improvement for Spring Petclinic
Our issue tracker is available here: https://github.com/spring-projects/spring-petclinic/issues
## Database configuration
-In its default configuration, Petclinic uses an in-memory database (HSQLDB) which
-gets populated at startup with data. A similar setup is provided for MySql in case a persistent database configuration is needed.
-Note that whenever the database type is changed, the data-access.properties file needs to be updated and the mysql-connector-java artifact from the pom.xml needs to be uncommented.
+In its default configuration, Petclinic uses an in-memory database (H2) which
+gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console`
+and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url.
+
+A similar setup is provided for MySql in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySql.
-You could start a MySql database with docker:
+You could start MySql locally with whatever installer works for your OS, or with docker:
```
-docker run -e MYSQL_ROOT_PASSWORD=petclinic -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8
+docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8
```
-## Working with Petclinic in Eclipse/STS
+Further documentation is provided [here](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt).
-### prerequisites
+## Working with Petclinic in your IDE
+
+### Prerequisites
The following items should be installed in your system:
-* Maven 3 (http://www.sonatype.com/books/mvnref-book/reference/installation.html)
+* Java 8 or newer.
* git command line tool (https://help.github.com/articles/set-up-git)
-* Eclipse with the m2e plugin (m2e is installed by default when using the STS (http://www.springsource.org/sts) distribution of Eclipse)
-
-Note: when m2e is available, there is an m2 icon in Help -> About dialog.
-If m2e is not there, just follow the install process here: http://eclipse.org/m2e/download/
-
+* Your preferred IDE
+ * Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in `Help -> About` dialog. If m2e is
+ not there, just follow the install process here: https://www.eclipse.org/m2e/
+ * [Spring Tools Suite](https://spring.io/tools) (STS)
+ * IntelliJ IDEA
+ * [VS Code](https://code.visualstudio.com)
### Steps:
-1) In the command line
-```
-git clone https://github.com/spring-projects/spring-petclinic.git
-```
-2) Inside Eclipse
-```
-File -> Import -> Maven -> Existing Maven project
-```
+1) On the command line
+ ```
+ git clone https://github.com/spring-projects/spring-petclinic.git
+ ```
+2) Inside Eclipse or STS
+ ```
+ File -> Import -> Maven -> Existing Maven project
+ ```
+
+ Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`.
+
+3) Inside IntelliJ IDEA
+ In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button.
+
+ CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`.
+
+ A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`.
+
+4) Navigate to Petclinic
+
+ Visit [http://localhost:8080](http://localhost:8080) in your browser.
## Looking for something in particular?
|Spring Boot Configuration | Class or Java property files |
|--------------------------|---|
-|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) |
-|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/resources) |
-|Caching | [CacheConfig](https://github.com/spring-projects/spring-petclinic/blob/master/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java) |
+|The Main Class | [PetClinicApplication](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java) |
+|Properties Files | [application.properties](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources) |
+|Caching | [CacheConfiguration](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) |
## Interesting Spring Petclinic branches and forks
-The Spring Petclinic master branch in the main
-[spring-projects](https://github.com/spring-projects/spring-petclinic)
-GitHub org is the "canonical" implementation, currently based on
-Spring Boot and Thymeleaf. There are quite a few forks in a special
-GitHub org [spring-petclinic](https://github.com/spring-petclinic). If
-you have a special interest in a different technology stack that could
-be used to implement the Pet Clinic then please join the community
-there.
-
-| Link | Main technologies |
-|----------------|-------------------|
-| [spring-framework-petclinic](https://github.com/spring-petclinic/spring-framework-petclinic) | Spring Framework XML configuration, JSP pages, 3 persistence layers: JDBC, JPA and Spring Data JPA |
-| [javaconfig branch](https://github.com/spring-petclinic/spring-framework-petclinic/tree/javaconfig) | Same frameworks as the [spring-framework-petclinic](https://github.com/spring-petclinic/spring-framework-petclinic) but with Java Configuration instead of XML |
-| [spring-petclinic-angular](https://github.com/spring-petclinic/spring-petclinic-angularjs) | AngularJS 1.x, Spring Boot and Spring Data JPA |
-| [spring-petclinic-microservices](https://github.com/spring-petclinic/spring-petclinic-microservices) | Distributed version of Spring Petclinic built with Spring Cloud |
-| [spring-petclinic-reactjs](https://github.com/spring-petclinic/spring-petclinic-reactjs) | ReactJS (with TypeScript) and Spring Boot |
+The Spring Petclinic "main" branch in the [spring-projects](https://github.com/spring-projects/spring-petclinic)
+GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are
+[quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in a special GitHub org
+[spring-petclinic](https://github.com/spring-petclinic). If you have a special interest in a different technology stack
+that could be used to implement the Pet Clinic then please join the community there.
## Interaction with other open source projects
@@ -98,8 +115,19 @@ Here is a list of them:
The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, features requests and submitting pull requests.
-For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at .
-
+For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at . If you have not previously done so, please fill out and submit the [Contributor License Agreement](https://cla.pivotal.io/sign/spring).
+# License
+The Spring PetClinic sample application is released under version 2.0 of the [Apache License](https://www.apache.org/licenses/LICENSE-2.0).
+[spring-petclinic]: https://github.com/spring-projects/spring-petclinic
+[spring-framework-petclinic]: https://github.com/spring-petclinic/spring-framework-petclinic
+[spring-petclinic-angularjs]: https://github.com/spring-petclinic/spring-petclinic-angularjs
+[javaconfig branch]: https://github.com/spring-petclinic/spring-framework-petclinic/tree/javaconfig
+[spring-petclinic-angular]: https://github.com/spring-petclinic/spring-petclinic-angular
+[spring-petclinic-microservices]: https://github.com/spring-petclinic/spring-petclinic-microservices
+[spring-petclinic-reactjs]: https://github.com/spring-petclinic/spring-petclinic-reactjs
+[spring-petclinic-graphql]: https://github.com/spring-petclinic/spring-petclinic-graphql
+[spring-petclinic-kotlin]: https://github.com/spring-petclinic/spring-petclinic-kotlin
+[spring-petclinic-rest]: https://github.com/spring-petclinic/spring-petclinic-rest
diff --git a/sonar-project.properties b/sonar-project.properties
deleted file mode 100755
index d84ed7c2d..000000000
--- a/sonar-project.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-# Required metadata
-sonar.projectKey=java-sonar-runner-simple
-sonar.projectName=Simple Java project analyzed with the SonarQube Runner
-sonar.projectVersion=1.0
-
-# Comma-separated paths to directories with sources (required)
-sonar.sources=src
-
-# Language
-sonar.language=java
-
-# Encoding of the source files
-sonar.sourceEncoding=UTF-8
\ No newline at end of file
diff --git a/src/checkstyle/nohttp-checkstyle-suppressions.xml b/src/checkstyle/nohttp-checkstyle-suppressions.xml
new file mode 100644
index 000000000..1b40e8b3f
--- /dev/null
+++ b/src/checkstyle/nohttp-checkstyle-suppressions.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/src/checkstyle/nohttp-checkstyle.xml b/src/checkstyle/nohttp-checkstyle.xml
new file mode 100644
index 000000000..e6205127b
--- /dev/null
+++ b/src/checkstyle/nohttp-checkstyle.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
index 224c326c7..191253587 100644
--- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
+++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -21,15 +21,15 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* PetClinic Spring Boot Application.
- *
+ *
* @author Dave Syer
*
*/
-@SpringBootApplication
+@SpringBootApplication(proxyBeanMethods = false)
public class PetClinicApplication {
- public static void main(String[] args) throws Exception {
- SpringApplication.run(PetClinicApplication.class, args);
- }
+ public static void main(String[] args) {
+ SpringApplication.run(PetClinicApplication.class, args);
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
index 86cc21092..4cb9ffc0c 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -31,20 +31,21 @@ import javax.persistence.MappedSuperclass;
*/
@MappedSuperclass
public class BaseEntity implements Serializable {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Integer id;
- public Integer getId() {
- return id;
- }
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
- public void setId(Integer id) {
- this.id = id;
- }
+ public Integer getId() {
+ return id;
+ }
- public boolean isNew() {
- return this.id == null;
- }
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public boolean isNew() {
+ return this.id == null;
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
index d66c97ae7..088e52e81 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -18,10 +18,9 @@ package org.springframework.samples.petclinic.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
-
/**
- * Simple JavaBean domain object adds a name property to BaseEntity. Used as a base class for objects
- * needing these properties.
+ * Simple JavaBean domain object adds a name property to BaseEntity. Used as
+ * a base class for objects needing these properties.
*
* @author Ken Krebs
* @author Juergen Hoeller
@@ -29,20 +28,20 @@ import javax.persistence.MappedSuperclass;
@MappedSuperclass
public class NamedEntity extends BaseEntity {
- @Column(name = "name")
- private String name;
+ @Column(name = "name")
+ private String name;
- public String getName() {
- return this.name;
- }
+ public String getName() {
+ return this.name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- @Override
- public String toString() {
- return this.getName();
- }
+ @Override
+ public String toString() {
+ return this.getName();
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java
index 4cb7481e0..15fabacc3 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/Person.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -17,8 +17,7 @@ package org.springframework.samples.petclinic.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
-
-import org.hibernate.validator.constraints.NotEmpty;
+import javax.validation.constraints.NotEmpty;
/**
* Simple JavaBean domain object representing an person.
@@ -28,28 +27,28 @@ import org.hibernate.validator.constraints.NotEmpty;
@MappedSuperclass
public class Person extends BaseEntity {
- @Column(name = "first_name")
- @NotEmpty
- private String firstName;
+ @Column(name = "first_name")
+ @NotEmpty
+ private String firstName;
- @Column(name = "last_name")
- @NotEmpty
- private String lastName;
+ @Column(name = "last_name")
+ @NotEmpty
+ private String lastName;
- public String getFirstName() {
- return this.firstName;
- }
+ public String getFirstName() {
+ return this.firstName;
+ }
- public void setFirstName(String firstName) {
- this.firstName = firstName;
- }
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
- public String getLastName() {
- return this.lastName;
- }
+ public String getLastName() {
+ return this.lastName;
+ }
- public void setLastName(String lastName) {
- this.lastName = lastName;
- }
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/package-info.java b/src/main/java/org/springframework/samples/petclinic/model/package-info.java
index 78294d130..37d6295e8 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/package-info.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/package-info.java
@@ -1,5 +1,20 @@
+/*
+ * Copyright 2012-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
* The classes in this package represent utilities used by the domain.
*/
package org.springframework.samples.petclinic.model;
-
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index f6fcae7ac..61083bc8d 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -27,8 +27,8 @@ import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotEmpty;
-import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.core.style.ToStringCreator;
@@ -45,112 +45,106 @@ import org.springframework.samples.petclinic.model.Person;
@Entity
@Table(name = "owners")
public class Owner extends Person {
- @Column(name = "address")
- @NotEmpty
- private String address;
- @Column(name = "city")
- @NotEmpty
- private String city;
+ @Column(name = "address")
+ @NotEmpty
+ private String address;
- @Column(name = "telephone")
- @NotEmpty
- @Digits(fraction = 0, integer = 10)
- private String telephone;
+ @Column(name = "city")
+ @NotEmpty
+ private String city;
- @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
- private Set pets;
+ @Column(name = "telephone")
+ @NotEmpty
+ @Digits(fraction = 0, integer = 10)
+ private String telephone;
+ @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+ private Set pets;
- public String getAddress() {
- return this.address;
- }
+ public String getAddress() {
+ return this.address;
+ }
- public void setAddress(String address) {
- this.address = address;
- }
+ public void setAddress(String address) {
+ this.address = address;
+ }
- public String getCity() {
- return this.city;
- }
+ public String getCity() {
+ return this.city;
+ }
- public void setCity(String city) {
- this.city = city;
- }
+ public void setCity(String city) {
+ this.city = city;
+ }
- public String getTelephone() {
- return this.telephone;
- }
+ public String getTelephone() {
+ return this.telephone;
+ }
- public void setTelephone(String telephone) {
- this.telephone = telephone;
- }
+ public void setTelephone(String telephone) {
+ this.telephone = telephone;
+ }
- protected Set getPetsInternal() {
- if (this.pets == null) {
- this.pets = new HashSet<>();
- }
- return this.pets;
- }
+ protected Set getPetsInternal() {
+ if (this.pets == null) {
+ this.pets = new HashSet<>();
+ }
+ return this.pets;
+ }
- protected void setPetsInternal(Set pets) {
- this.pets = pets;
- }
+ protected void setPetsInternal(Set pets) {
+ this.pets = pets;
+ }
- public List getPets() {
- List sortedPets = new ArrayList<>(getPetsInternal());
- PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
- return Collections.unmodifiableList(sortedPets);
- }
+ public List getPets() {
+ List sortedPets = new ArrayList<>(getPetsInternal());
+ PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
+ return Collections.unmodifiableList(sortedPets);
+ }
- public void addPet(Pet pet) {
- if (pet.isNew()) {
- getPetsInternal().add(pet);
- }
- pet.setOwner(this);
- }
+ public void addPet(Pet pet) {
+ if (pet.isNew()) {
+ getPetsInternal().add(pet);
+ }
+ pet.setOwner(this);
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- *
- * @param name to test
- * @return true if pet name is already in use
- */
- public Pet getPet(String name) {
- return getPet(name, false);
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @return true if pet name is already in use
+ */
+ public Pet getPet(String name) {
+ return getPet(name, false);
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- *
- * @param name to test
- * @return true if pet name is already in use
- */
- public Pet getPet(String name, boolean ignoreNew) {
- name = name.toLowerCase();
- for (Pet pet : getPetsInternal()) {
- if (!ignoreNew || !pet.isNew()) {
- String compName = pet.getName();
- compName = compName.toLowerCase();
- if (compName.equals(name)) {
- return pet;
- }
- }
- }
- return null;
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @return true if pet name is already in use
+ */
+ public Pet getPet(String name, boolean ignoreNew) {
+ name = name.toLowerCase();
+ for (Pet pet : getPetsInternal()) {
+ if (!ignoreNew || !pet.isNew()) {
+ String compName = pet.getName();
+ compName = compName.toLowerCase();
+ if (compName.equals(name)) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
- @Override
- public String toString() {
- return new ToStringCreator(this)
+ @Override
+ public String toString() {
+ return new ToStringCreator(this)
+
+ .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName())
+ .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city)
+ .append("telephone", this.telephone).toString();
+ }
- .append("id", this.getId())
- .append("new", this.isNew())
- .append("lastName", this.getLastName())
- .append("firstName", this.getFirstName())
- .append("address", this.address)
- .append("city", this.city)
- .append("telephone", this.telephone)
- .toString();
- }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
index ef3169b70..79aa4cd9b 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -15,22 +15,21 @@
*/
package org.springframework.samples.petclinic.owner;
-import java.util.Collection;
-import java.util.Map;
-
-import javax.validation.Valid;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.visit.VisitRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
+import javax.validation.Valid;
+import java.util.Collection;
+import java.util.Map;
+
/**
* @author Juergen Hoeller
* @author Ken Krebs
@@ -40,97 +39,107 @@ import org.springframework.web.servlet.ModelAndView;
@Controller
class OwnerController {
- private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
- private final OwnerRepository owners;
+ private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
+ private final OwnerRepository owners;
- @Autowired
- public OwnerController(OwnerRepository clinicService) {
- this.owners = clinicService;
- }
+ private VisitRepository visits;
- @InitBinder
- public void setAllowedFields(WebDataBinder dataBinder) {
- dataBinder.setDisallowedFields("id");
- }
+ public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
+ this.owners = clinicService;
+ this.visits = visits;
+ }
- @RequestMapping(value = "/owners/new", method = RequestMethod.GET)
- public String initCreationForm(Map model) {
- Owner owner = new Owner();
- model.put("owner", owner);
- return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
- }
+ @InitBinder
+ public void setAllowedFields(WebDataBinder dataBinder) {
+ dataBinder.setDisallowedFields("id");
+ }
- @RequestMapping(value = "/owners/new", method = RequestMethod.POST)
- public String processCreationForm(@Valid Owner owner, BindingResult result) {
- if (result.hasErrors()) {
- return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
- } else {
- this.owners.save(owner);
- return "redirect:/owners/" + owner.getId();
- }
- }
+ @GetMapping("/owners/new")
+ public String initCreationForm(Map model) {
+ Owner owner = new Owner();
+ model.put("owner", owner);
+ return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
+ }
- @RequestMapping(value = "/owners/find", method = RequestMethod.GET)
- public String initFindForm(Map model) {
- model.put("owner", new Owner());
- return "owners/findOwners";
- }
+ @PostMapping("/owners/new")
+ public String processCreationForm(@Valid Owner owner, BindingResult result) {
+ if (result.hasErrors()) {
+ return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
+ }
+ else {
+ this.owners.save(owner);
+ return "redirect:/owners/" + owner.getId();
+ }
+ }
- @RequestMapping(value = "/owners", method = RequestMethod.GET)
- public String processFindForm(Owner owner, BindingResult result, Map model) {
+ @GetMapping("/owners/find")
+ public String initFindForm(Map model) {
+ model.put("owner", new Owner());
+ return "owners/findOwners";
+ }
- // allow parameterless GET request for /owners to return all records
- if (owner.getLastName() == null) {
- owner.setLastName(""); // empty string signifies broadest possible search
- }
+ @GetMapping("/owners")
+ public String processFindForm(Owner owner, BindingResult result, Map model) {
- // find owners by last name
- Collection results = this.owners.findByLastName(owner.getLastName());
- if (results.isEmpty()) {
- // no owners found
- result.rejectValue("lastName", "notFound", "not found");
- return "owners/findOwners";
- } else if (results.size() == 1) {
- // 1 owner found
- owner = results.iterator().next();
- return "redirect:/owners/" + owner.getId();
- } else {
- // multiple owners found
- model.put("selections", results);
- return "owners/ownersList";
- }
- }
+ // allow parameterless GET request for /owners to return all records
+ if (owner.getLastName() == null) {
+ owner.setLastName(""); // empty string signifies broadest possible search
+ }
- @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.GET)
- public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
- Owner owner = this.owners.findById(ownerId);
- model.addAttribute(owner);
- return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
- }
+ // find owners by last name
+ Collection results = this.owners.findByLastName(owner.getLastName());
+ if (results.isEmpty()) {
+ // no owners found
+ result.rejectValue("lastName", "notFound", "not found");
+ return "owners/findOwners";
+ }
+ else if (results.size() == 1) {
+ // 1 owner found
+ owner = results.iterator().next();
+ return "redirect:/owners/" + owner.getId();
+ }
+ else {
+ // multiple owners found
+ model.put("selections", results);
+ return "owners/ownersList";
+ }
+ }
- @RequestMapping(value = "/owners/{ownerId}/edit", method = RequestMethod.POST)
- public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) {
- if (result.hasErrors()) {
- return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
- } else {
- owner.setId(ownerId);
- this.owners.save(owner);
- return "redirect:/owners/{ownerId}";
- }
- }
+ @GetMapping("/owners/{ownerId}/edit")
+ public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
+ Owner owner = this.owners.findById(ownerId);
+ model.addAttribute(owner);
+ return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
+ }
- /**
- * Custom handler for displaying an owner.
- *
- * @param ownerId the ID of the owner to display
- * @return a ModelMap with the model attributes for the view
- */
- @RequestMapping("/owners/{ownerId}")
- public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
- ModelAndView mav = new ModelAndView("owners/ownerDetails");
- mav.addObject(this.owners.findById(ownerId));
- return mav;
- }
+ @PostMapping("/owners/{ownerId}/edit")
+ public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result,
+ @PathVariable("ownerId") int ownerId) {
+ if (result.hasErrors()) {
+ return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
+ }
+ else {
+ owner.setId(ownerId);
+ this.owners.save(owner);
+ return "redirect:/owners/{ownerId}";
+ }
+ }
+
+ /**
+ * Custom handler for displaying an owner.
+ * @param ownerId the ID of the owner to display
+ * @return a ModelMap with the model attributes for the view
+ */
+ @GetMapping("/owners/{ownerId}")
+ public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
+ ModelAndView mav = new ModelAndView("owners/ownerDetails");
+ Owner owner = this.owners.findById(ownerId);
+ for (Pet pet : owner.getPets()) {
+ pet.setVisitsInternal(visits.findByPetId(pet.getId()));
+ }
+ mav.addObject(owner);
+ return mav;
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
index 068f5245d..0613e928a 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -23,8 +23,10 @@ import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
/**
- * Repository class for Owner domain objects All method names are compliant with Spring Data naming
- * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation
+ * Repository class for Owner domain objects All method names are compliant
+ * with Spring Data naming conventions so this interface can easily be extended for Spring
+ * Data. See:
+ * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@@ -33,31 +35,30 @@ import org.springframework.transaction.annotation.Transactional;
*/
public interface OwnerRepository extends Repository {
- /**
- * Retrieve {@link Owner}s from the data store by last name, returning all owners
- * whose last name starts with the given name.
- * @param lastName Value to search for
- * @return a Collection of matching {@link Owner}s (or an empty Collection if none
- * found)
- */
- @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
- @Transactional(readOnly = true)
- Collection findByLastName(@Param("lastName") String lastName);
+ /**
+ * Retrieve {@link Owner}s from the data store by last name, returning all owners
+ * whose last name starts with the given name.
+ * @param lastName Value to search for
+ * @return a Collection of matching {@link Owner}s (or an empty Collection if none
+ * found)
+ */
+ @Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
+ @Transactional(readOnly = true)
+ Collection findByLastName(@Param("lastName") String lastName);
- /**
- * Retrieve an {@link Owner} from the data store by id.
- * @param id the id to search for
- * @return the {@link Owner} if found
- */
- @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
- @Transactional(readOnly = true)
- Owner findById(@Param("id") Integer id);
-
- /**
- * Save an {@link Owner} to the data store, either inserting or updating it.
- * @param owner the {@link Owner} to save
- */
- void save(Owner owner);
+ /**
+ * Retrieve an {@link Owner} from the data store by id.
+ * @param id the id to search for
+ * @return the {@link Owner} if found
+ */
+ @Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
+ @Transactional(readOnly = true)
+ Owner findById(@Param("id") Integer id);
+ /**
+ * Save an {@link Owner} to the data store, either inserting or updating it.
+ * @param owner the {@link Owner} to save
+ */
+ void save(Owner owner);
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
old mode 100644
new mode 100755
index e8df85e91..2b68005fd
--- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -15,24 +15,21 @@
*/
package org.springframework.samples.petclinic.owner;
+import java.time.LocalDate;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
-import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
-import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
+import javax.persistence.Transient;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
@@ -51,67 +48,65 @@ import org.springframework.samples.petclinic.visit.Visit;
@Table(name = "pets")
public class Pet extends NamedEntity {
- @Column(name = "birth_date")
- @Temporal(TemporalType.DATE)
- @DateTimeFormat(pattern = "yyyy/MM/dd")
- private Date birthDate;
+ @Column(name = "birth_date")
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate birthDate;
- @ManyToOne
- @JoinColumn(name = "type_id")
- private PetType type;
+ @ManyToOne
+ @JoinColumn(name = "type_id")
+ private PetType type;
- @ManyToOne
- @JoinColumn(name = "owner_id")
- private Owner owner;
+ @ManyToOne
+ @JoinColumn(name = "owner_id")
+ private Owner owner;
- @OneToMany(cascade = CascadeType.ALL, mappedBy = "petId", fetch = FetchType.EAGER)
- private Set visits = new LinkedHashSet<>();
+ @Transient
+ private Set visits = new LinkedHashSet<>();
- public void setBirthDate(Date birthDate) {
- this.birthDate = birthDate;
- }
+ public void setBirthDate(LocalDate birthDate) {
+ this.birthDate = birthDate;
+ }
- public Date getBirthDate() {
- return this.birthDate;
- }
+ public LocalDate getBirthDate() {
+ return this.birthDate;
+ }
- public PetType getType() {
- return this.type;
- }
+ public PetType getType() {
+ return this.type;
+ }
- public void setType(PetType type) {
- this.type = type;
- }
+ public void setType(PetType type) {
+ this.type = type;
+ }
- public Owner getOwner() {
- return this.owner;
- }
+ public Owner getOwner() {
+ return this.owner;
+ }
- protected void setOwner(Owner owner) {
- this.owner = owner;
- }
+ protected void setOwner(Owner owner) {
+ this.owner = owner;
+ }
- protected Set getVisitsInternal() {
- if (this.visits == null) {
- this.visits = new HashSet<>();
- }
- return this.visits;
- }
+ protected Set getVisitsInternal() {
+ if (this.visits == null) {
+ this.visits = new HashSet<>();
+ }
+ return this.visits;
+ }
- protected void setVisitsInternal(Set visits) {
- this.visits = visits;
- }
+ protected void setVisitsInternal(Collection visits) {
+ this.visits = new LinkedHashSet<>(visits);
+ }
- public List getVisits() {
- List sortedVisits = new ArrayList<>(getVisitsInternal());
- PropertyComparator.sort(sortedVisits,
- new MutableSortDefinition("date", false, false));
- return Collections.unmodifiableList(sortedVisits);
- }
+ public List getVisits() {
+ List sortedVisits = new ArrayList<>(getVisitsInternal());
+ PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
+ return Collections.unmodifiableList(sortedVisits);
+ }
- public void addVisit(Visit visit) {
- getVisitsInternal().add(visit);
- visit.setPetId(this.getId());
- }
+ public void addVisit(Visit visit) {
+ getVisitsInternal().add(visit);
+ visit.setPetId(this.getId());
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
index 45b87c6b1..a55e599af 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -15,21 +15,15 @@
*/
package org.springframework.samples.petclinic.owner;
-import java.util.Collection;
-
-import javax.validation.Valid;
-
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Collection;
/**
* @author Juergen Hoeller
@@ -40,77 +34,80 @@ import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/owners/{ownerId}")
class PetController {
- private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
- private final PetRepository pets;
- private final OwnerRepository owners;
+ private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
- @Autowired
- public PetController(PetRepository pets, OwnerRepository owners) {
- this.pets = pets;
- this.owners = owners;
- }
+ private final PetRepository pets;
- @ModelAttribute("types")
- public Collection populatePetTypes() {
- return this.pets.findPetTypes();
- }
+ private final OwnerRepository owners;
- @ModelAttribute("owner")
- public Owner findOwner(@PathVariable("ownerId") int ownerId) {
- return this.owners.findById(ownerId);
- }
+ public PetController(PetRepository pets, OwnerRepository owners) {
+ this.pets = pets;
+ this.owners = owners;
+ }
- @InitBinder("owner")
- public void initOwnerBinder(WebDataBinder dataBinder) {
- dataBinder.setDisallowedFields("id");
- }
+ @ModelAttribute("types")
+ public Collection populatePetTypes() {
+ return this.pets.findPetTypes();
+ }
- @InitBinder("pet")
- public void initPetBinder(WebDataBinder dataBinder) {
- dataBinder.setValidator(new PetValidator());
- }
+ @ModelAttribute("owner")
+ public Owner findOwner(@PathVariable("ownerId") int ownerId) {
+ return this.owners.findById(ownerId);
+ }
- @RequestMapping(value = "/pets/new", method = RequestMethod.GET)
- public String initCreationForm(Owner owner, ModelMap model) {
- Pet pet = new Pet();
- owner.addPet(pet);
- model.put("pet", pet);
- return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
- }
+ @InitBinder("owner")
+ public void initOwnerBinder(WebDataBinder dataBinder) {
+ dataBinder.setDisallowedFields("id");
+ }
- @RequestMapping(value = "/pets/new", method = RequestMethod.POST)
- public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
- if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null){
- result.rejectValue("name", "duplicate", "already exists");
- }
- owner.addPet(pet);
- if (result.hasErrors()) {
- model.put("pet", pet);
- return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
- } else {
- this.pets.save(pet);
- return "redirect:/owners/{ownerId}";
- }
- }
+ @InitBinder("pet")
+ public void initPetBinder(WebDataBinder dataBinder) {
+ dataBinder.setValidator(new PetValidator());
+ }
- @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.GET)
- public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
- Pet pet = this.pets.findById(petId);
- model.put("pet", pet);
- return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
- }
+ @GetMapping("/pets/new")
+ public String initCreationForm(Owner owner, ModelMap model) {
+ Pet pet = new Pet();
+ owner.addPet(pet);
+ model.put("pet", pet);
+ return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
+ }
- @RequestMapping(value = "/pets/{petId}/edit", method = RequestMethod.POST)
- public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
- if (result.hasErrors()) {
- pet.setOwner(owner);
- model.put("pet", pet);
- return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
- } else {
- owner.addPet(pet);
- this.pets.save(pet);
- return "redirect:/owners/{ownerId}";
- }
- }
+ @PostMapping("/pets/new")
+ public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
+ if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
+ result.rejectValue("name", "duplicate", "already exists");
+ }
+ owner.addPet(pet);
+ if (result.hasErrors()) {
+ model.put("pet", pet);
+ return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
+ }
+ else {
+ this.pets.save(pet);
+ return "redirect:/owners/{ownerId}";
+ }
+ }
+
+ @GetMapping("/pets/{petId}/edit")
+ public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
+ Pet pet = this.pets.findById(petId);
+ model.put("pet", pet);
+ return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
+ }
+
+ @PostMapping("/pets/{petId}/edit")
+ public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
+ if (result.hasErrors()) {
+ pet.setOwner(owner);
+ model.put("pet", pet);
+ return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
+ }
+ else {
+ owner.addPet(pet);
+ this.pets.save(pet);
+ return "redirect:/owners/{ownerId}";
+ }
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java
index b0ec5db23..9d25b095b 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -22,8 +22,10 @@ import org.springframework.data.repository.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
- * Repository class for Pet domain objects All method names are compliant with Spring Data naming
- * conventions so this interface can easily be extended for Spring Data See here: http://static.springsource.org/spring-data/jpa/docs/current/reference/html/jpa.repositories.html#jpa.query-methods.query-creation
+ * Repository class for Pet domain objects All method names are compliant
+ * with Spring Data naming conventions so this interface can easily be extended for Spring
+ * Data. See:
+ * https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
*
* @author Ken Krebs
* @author Juergen Hoeller
@@ -32,27 +34,26 @@ import org.springframework.transaction.annotation.Transactional;
*/
public interface PetRepository extends Repository {
- /**
- * Retrieve all {@link PetType}s from the data store.
- * @return a Collection of {@link PetType}s.
- */
- @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
- @Transactional(readOnly = true)
- List findPetTypes();
+ /**
+ * Retrieve all {@link PetType}s from the data store.
+ * @return a Collection of {@link PetType}s.
+ */
+ @Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
+ @Transactional(readOnly = true)
+ List findPetTypes();
- /**
- * Retrieve a {@link Pet} from the data store by id.
- * @param id the id to search for
- * @return the {@link Pet} if found
- */
- @Transactional(readOnly = true)
- Pet findById(Integer id);
+ /**
+ * Retrieve a {@link Pet} from the data store by id.
+ * @param id the id to search for
+ * @return the {@link Pet} if found
+ */
+ @Transactional(readOnly = true)
+ Pet findById(Integer id);
- /**
- * Save a {@link Pet} to the data store, either inserting or updating it.
- * @param pet the {@link Pet} to save
- */
- void save(Pet pet);
+ /**
+ * Save a {@link Pet} to the data store, either inserting or updating it.
+ * @param pet the {@link Pet} to save
+ */
+ void save(Pet pet);
}
-
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
index ac827b310..6f0aa58d3 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -21,8 +21,7 @@ import javax.persistence.Table;
import org.springframework.samples.petclinic.model.NamedEntity;
/**
- * @author Juergen Hoeller
- * Can be Cat, Dog, Hamster...
+ * @author Juergen Hoeller Can be Cat, Dog, Hamster...
*/
@Entity
@Table(name = "types")
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
index 78451ca28..4940bcb38 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -15,7 +15,6 @@
*/
package org.springframework.samples.petclinic.owner;
-
import java.text.ParseException;
import java.util.Collection;
import java.util.Locale;
@@ -25,11 +24,10 @@ import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
/**
- * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting from Spring 3.0, Formatters have
- * come as an improvement in comparison to legacy PropertyEditors. See the following links for more details: - The
- * Spring ref doc: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html#format-Formatter-SPI
- * - A nice blog entry from Gordon Dickens: http://gordondickens.com/wordpress/2010/09/30/using-spring-3-0-custom-type-converter/
- *
+ * Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting
+ * from Spring 3.0, Formatters have come as an improvement in comparison to legacy
+ * PropertyEditors. See the following links for more details: - The Spring ref doc:
+ * https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format
*
* @author Mark Fisher
* @author Juergen Hoeller
@@ -38,28 +36,27 @@ import org.springframework.stereotype.Component;
@Component
public class PetTypeFormatter implements Formatter {
- private final PetRepository pets;
+ private final PetRepository pets;
+ @Autowired
+ public PetTypeFormatter(PetRepository pets) {
+ this.pets = pets;
+ }
- @Autowired
- public PetTypeFormatter(PetRepository pets) {
- this.pets = pets;
- }
+ @Override
+ public String print(PetType petType, Locale locale) {
+ return petType.getName();
+ }
- @Override
- public String print(PetType petType, Locale locale) {
- return petType.getName();
- }
-
- @Override
- public PetType parse(String text, Locale locale) throws ParseException {
- Collection findPetTypes = this.pets.findPetTypes();
- for (PetType type : findPetTypes) {
- if (type.getName().equals(text)) {
- return type;
- }
- }
- throw new ParseException("type not found: " + text, 0);
- }
+ @Override
+ public PetType parse(String text, Locale locale) throws ParseException {
+ Collection findPetTypes = this.pets.findPetTypes();
+ for (PetType type : findPetTypes) {
+ if (type.getName().equals(text)) {
+ return type;
+ }
+ }
+ throw new ParseException("type not found: " + text, 0);
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java
index 1a3d92e9e..e1370b428 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -22,7 +22,8 @@ import org.springframework.validation.Validator;
/**
* Validator for Pet forms.
*
- * We're not using Bean Validation annotations here because it is easier to define such validation rule in Java.
+ * We're not using Bean Validation annotations here because it is easier to define such
+ * validation rule in Java.
*
*
* @author Ken Krebs
@@ -30,35 +31,34 @@ import org.springframework.validation.Validator;
*/
public class PetValidator implements Validator {
- private static final String REQUIRED = "required";
+ private static final String REQUIRED = "required";
- @Override
- public void validate(Object obj, Errors errors) {
- Pet pet = (Pet) obj;
- String name = pet.getName();
- // name validation
- if (!StringUtils.hasLength(name)) {
- errors.rejectValue("name", REQUIRED, REQUIRED);
- }
+ @Override
+ public void validate(Object obj, Errors errors) {
+ Pet pet = (Pet) obj;
+ String name = pet.getName();
+ // name validation
+ if (!StringUtils.hasLength(name)) {
+ errors.rejectValue("name", REQUIRED, REQUIRED);
+ }
- // type validation
- if (pet.isNew() && pet.getType() == null) {
- errors.rejectValue("type", REQUIRED, REQUIRED);
- }
+ // type validation
+ if (pet.isNew() && pet.getType() == null) {
+ errors.rejectValue("type", REQUIRED, REQUIRED);
+ }
- // birth date validation
- if (pet.getBirthDate() == null) {
- errors.rejectValue("birthDate", REQUIRED, REQUIRED);
- }
- }
-
- /**
- * This Validator validates *just* Pet instances
- */
- @Override
- public boolean supports(Class> clazz) {
- return Pet.class.isAssignableFrom(clazz);
- }
+ // birth date validation
+ if (pet.getBirthDate() == null) {
+ errors.rejectValue("birthDate", REQUIRED, REQUIRED);
+ }
+ }
+ /**
+ * This Validator validates *just* Pet instances
+ */
+ @Override
+ public boolean supports(Class> clazz) {
+ return Pet.class.isAssignableFrom(clazz);
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
index d98c5dd0f..375980312 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -19,17 +19,16 @@ import java.util.Map;
import javax.validation.Valid;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.visit.Visit;
import org.springframework.samples.petclinic.visit.VisitRepository;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.PostMapping;
/**
* @author Juergen Hoeller
@@ -41,55 +40,53 @@ import org.springframework.web.bind.annotation.RequestMethod;
@Controller
class VisitController {
- private final VisitRepository visits;
- private final PetRepository pets;
+ private final VisitRepository visits;
+ private final PetRepository pets;
- @Autowired
- public VisitController(VisitRepository visits, PetRepository pets) {
- this.visits = visits;
- this.pets = pets;
- }
+ public VisitController(VisitRepository visits, PetRepository pets) {
+ this.visits = visits;
+ this.pets = pets;
+ }
- @InitBinder
- public void setAllowedFields(WebDataBinder dataBinder) {
- dataBinder.setDisallowedFields("id");
- }
+ @InitBinder
+ public void setAllowedFields(WebDataBinder dataBinder) {
+ dataBinder.setDisallowedFields("id");
+ }
- /**
- * Called before each and every @RequestMapping annotated method.
- * 2 goals:
- * - Make sure we always have fresh data
- * - Since we do not use the session scope, make sure that Pet object always has an id
- * (Even though id is not part of the form fields)
- *
- * @param petId
- * @return Pet
- */
- @ModelAttribute("visit")
- public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) {
- Pet pet = this.pets.findById(petId);
- model.put("pet", pet);
- Visit visit = new Visit();
- pet.addVisit(visit);
- return visit;
- }
+ /**
+ * Called before each and every @RequestMapping annotated method. 2 goals: - Make sure
+ * we always have fresh data - Since we do not use the session scope, make sure that
+ * Pet object always has an id (Even though id is not part of the form fields)
+ * @param petId
+ * @return Pet
+ */
+ @ModelAttribute("visit")
+ public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) {
+ Pet pet = this.pets.findById(petId);
+ pet.setVisitsInternal(this.visits.findByPetId(petId));
+ model.put("pet", pet);
+ Visit visit = new Visit();
+ pet.addVisit(visit);
+ return visit;
+ }
- // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
- @RequestMapping(value = "/owners/*/pets/{petId}/visits/new", method = RequestMethod.GET)
- public String initNewVisitForm(@PathVariable("petId") int petId, Map model) {
- return "pets/createOrUpdateVisitForm";
- }
+ // Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
+ @GetMapping("/owners/*/pets/{petId}/visits/new")
+ public String initNewVisitForm(@PathVariable("petId") int petId, Map model) {
+ return "pets/createOrUpdateVisitForm";
+ }
- // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
- @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/visits/new", method = RequestMethod.POST)
- public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
- if (result.hasErrors()) {
- return "pets/createOrUpdateVisitForm";
- } else {
- this.visits.save(visit);
- return "redirect:/owners/{ownerId}";
- }
- }
+ // Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
+ @PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
+ public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
+ if (result.hasErrors()) {
+ return "pets/createOrUpdateVisitForm";
+ }
+ else {
+ this.visits.save(visit);
+ return "redirect:/owners/{ownerId}";
+ }
+ }
}
diff --git a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java b/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java
deleted file mode 100755
index 13e194c35..000000000
--- a/src/main/java/org/springframework/samples/petclinic/system/CacheConfig.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.springframework.samples.petclinic.system;
-
-import javax.cache.configuration.Configuration;
-import javax.cache.configuration.MutableConfiguration;
-
-import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Profile;
-
-/**
- * Cache could be disabled in unit test.
- */
-@org.springframework.context.annotation.Configuration
-@EnableCaching
-@Profile("production")
-class CacheConfig {
-
- @Bean
- public JCacheManagerCustomizer cacheManagerCustomizer() {
- return cm -> {
- Configuration