mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-23 07:45:49 +00:00
adding checkstyle.xml and formatting the files
This commit is contained in:
parent
8c6f7820ff
commit
e063ff2dbf
38 changed files with 1499 additions and 1132 deletions
|
@ -10,7 +10,7 @@ indent_style = space
|
||||||
[*.{java,xml}]
|
[*.{java,xml}]
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
indent_style = tab
|
indent_style = space
|
||||||
tab_width = 4
|
tab_width = 4
|
||||||
|
|
||||||
[{pom,wro}.xml]
|
[{pom,wro}.xml]
|
||||||
|
|
57
pom.xml
57
pom.xml
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
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">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.springframework.samples</groupId>
|
<groupId>org.springframework.samples</groupId>
|
||||||
<artifactId>spring-petclinic</artifactId>
|
<artifactId>spring-petclinic</artifactId>
|
||||||
|
@ -62,12 +62,12 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.junit.vintage</groupId>
|
<groupId>org.junit.vintage</groupId>
|
||||||
<artifactId>junit-vintage-engine</artifactId>
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Databases - Uses H2 by default -->
|
<!-- Databases - Uses H2 by default -->
|
||||||
|
@ -92,6 +92,12 @@
|
||||||
<artifactId>ehcache</artifactId>
|
<artifactId>ehcache</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- webjars -->
|
<!-- webjars -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.webjars</groupId>
|
<groupId>org.webjars</groupId>
|
||||||
|
@ -123,47 +129,28 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>io.spring.javaformat</groupId>
|
|
||||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
|
||||||
<version>${spring-format.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>validate</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
<version>3.1.1</version>
|
<version>3.1.1</version>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>src/checkstyle/checkstyle.xml</configLocation>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<consoleOutput>true</consoleOutput>
|
||||||
|
<failsOnError>true</failsOnError>
|
||||||
|
<linkXRef>false</linkXRef>
|
||||||
|
</configuration>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>8.32</version>
|
<version>8.32</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.spring.nohttp</groupId>
|
|
||||||
<artifactId>nohttp-checkstyle</artifactId>
|
|
||||||
<version>${nohttp-checkstyle.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>nohttp-checkstyle-validation</id>
|
<id>validate</id>
|
||||||
<phase>validate</phase>
|
<phase>validate</phase>
|
||||||
<configuration>
|
|
||||||
<configLocation>src/checkstyle/nohttp-checkstyle.xml</configLocation>
|
|
||||||
<suppressionsLocation>src/checkstyle/nohttp-checkstyle-suppressions.xml</suppressionsLocation>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<sourceDirectories>${basedir}</sourceDirectories>
|
|
||||||
<includes>**/*</includes>
|
|
||||||
<excludes>**/.git/**/*,**/.idea/**/*,**/target/**/,**/.flattened-pom.xml,**/*.class</excludes>
|
|
||||||
</configuration>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>check</goal>
|
<goal>check</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
|
333
src/checkstyle/checkstyle.xml
Normal file
333
src/checkstyle/checkstyle.xml
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE module PUBLIC
|
||||||
|
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||||
|
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Checkstyle configuration that checks the Google coding conventions from Google Java Style
|
||||||
|
that can be found at https://google.github.io/styleguide/javaguide.html
|
||||||
|
|
||||||
|
Checkstyle is very configurable. Be sure to read the documentation at
|
||||||
|
http://checkstyle.org (or in your downloaded distribution).
|
||||||
|
|
||||||
|
To completely disable a check, just comment it out or delete it from the file.
|
||||||
|
To suppress certain violations please review suppression filters.
|
||||||
|
|
||||||
|
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<module name = "Checker">
|
||||||
|
<property name="charset" value="UTF-8"/>
|
||||||
|
|
||||||
|
<property name="severity" value="error"/>
|
||||||
|
|
||||||
|
<property name="fileExtensions" value="java, properties, xml"/>
|
||||||
|
<!-- Excludes all 'module-info.java' files -->
|
||||||
|
<!-- See https://checkstyle.org/config_filefilters.html -->
|
||||||
|
<module name="BeforeExecutionExclusionFileFilter">
|
||||||
|
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||||
|
</module>
|
||||||
|
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
||||||
|
<module name="SuppressionFilter">
|
||||||
|
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
|
||||||
|
default="checkstyle-suppressions.xml" />
|
||||||
|
<property name="optional" value="true"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<!-- Checks for whitespace -->
|
||||||
|
<!-- See http://checkstyle.org/config_whitespace.html -->
|
||||||
|
<module name="FileTabCharacter">
|
||||||
|
<property name="eachLine" value="true"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<module name="LineLength">
|
||||||
|
<property name="fileExtensions" value="java"/>
|
||||||
|
<property name="max" value="120"/>
|
||||||
|
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||||
|
</module>
|
||||||
|
|
||||||
|
<module name="TreeWalker">
|
||||||
|
<module name="OuterTypeFilename"/>
|
||||||
|
<module name="IllegalTokenText">
|
||||||
|
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||||
|
<property name="format"
|
||||||
|
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||||
|
<property name="message"
|
||||||
|
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||||
|
</module>
|
||||||
|
<module name="AvoidEscapedUnicodeCharacters">
|
||||||
|
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||||
|
<property name="allowByTailComment" value="true"/>
|
||||||
|
<property name="allowNonPrintableEscapes" value="true"/>
|
||||||
|
</module>
|
||||||
|
<module name="AvoidStarImport"/>
|
||||||
|
<module name="OneTopLevelClass"/>
|
||||||
|
<module name="NoLineWrap">
|
||||||
|
<property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
|
||||||
|
</module>
|
||||||
|
<module name="EmptyBlock">
|
||||||
|
<property name="option" value="TEXT"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||||
|
</module>
|
||||||
|
<module name="NeedBraces">
|
||||||
|
<property name="tokens"
|
||||||
|
value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
|
||||||
|
</module>
|
||||||
|
<module name="LeftCurly">
|
||||||
|
<property name="tokens"
|
||||||
|
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
|
||||||
|
INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
|
||||||
|
LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
|
||||||
|
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
|
||||||
|
OBJBLOCK, STATIC_INIT"/>
|
||||||
|
</module>
|
||||||
|
<module name="RightCurly">
|
||||||
|
<property name="id" value="RightCurlySame"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
|
||||||
|
LITERAL_DO"/>
|
||||||
|
</module>
|
||||||
|
<module name="RightCurly">
|
||||||
|
<property name="id" value="RightCurlyAlone"/>
|
||||||
|
<property name="option" value="alone"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
|
||||||
|
INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="SuppressionXpathSingleFilter">
|
||||||
|
<!-- suppresion is required till https://github.com/checkstyle/checkstyle/issues/7541 -->
|
||||||
|
<property name="id" value="RightCurlyAlone"/>
|
||||||
|
<property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
|
||||||
|
or preceding-sibling::*[last()][self::LCURLY]]"/>
|
||||||
|
</module>
|
||||||
|
<module name="WhitespaceAfter">
|
||||||
|
<property name="tokens"
|
||||||
|
value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE,
|
||||||
|
LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/>
|
||||||
|
</module>
|
||||||
|
<module name="WhitespaceAround">
|
||||||
|
<property name="allowEmptyConstructors" value="true"/>
|
||||||
|
<property name="allowEmptyLambdas" value="true"/>
|
||||||
|
<property name="allowEmptyMethods" value="true"/>
|
||||||
|
<property name="allowEmptyTypes" value="true"/>
|
||||||
|
<property name="allowEmptyLoops" value="true"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
|
||||||
|
BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
|
||||||
|
LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
|
||||||
|
LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
|
||||||
|
LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
|
||||||
|
NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
|
||||||
|
SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
|
||||||
|
<message key="ws.notFollowed"
|
||||||
|
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
|
||||||
|
<message key="ws.notPreceded"
|
||||||
|
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
||||||
|
</module>
|
||||||
|
<module name="OneStatementPerLine"/>
|
||||||
|
<module name="MultipleVariableDeclarations"/>
|
||||||
|
<module name="ArrayTypeStyle"/>
|
||||||
|
<module name="MissingSwitchDefault"/>
|
||||||
|
<module name="FallThrough"/>
|
||||||
|
<module name="UpperEll"/>
|
||||||
|
<module name="ModifierOrder"/>
|
||||||
|
<module name="EmptyLineSeparator">
|
||||||
|
<property name="tokens"
|
||||||
|
value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||||
|
STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||||
|
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||||
|
</module>
|
||||||
|
<module name="SeparatorWrap">
|
||||||
|
<property name="id" value="SeparatorWrapDot"/>
|
||||||
|
<property name="tokens" value="DOT"/>
|
||||||
|
<property name="option" value="nl"/>
|
||||||
|
</module>
|
||||||
|
<module name="SeparatorWrap">
|
||||||
|
<property name="id" value="SeparatorWrapComma"/>
|
||||||
|
<property name="tokens" value="COMMA"/>
|
||||||
|
<property name="option" value="EOL"/>
|
||||||
|
</module>
|
||||||
|
<module name="SeparatorWrap">
|
||||||
|
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/258 -->
|
||||||
|
<property name="id" value="SeparatorWrapEllipsis"/>
|
||||||
|
<property name="tokens" value="ELLIPSIS"/>
|
||||||
|
<property name="option" value="EOL"/>
|
||||||
|
</module>
|
||||||
|
<module name="SeparatorWrap">
|
||||||
|
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/259 -->
|
||||||
|
<property name="id" value="SeparatorWrapArrayDeclarator"/>
|
||||||
|
<property name="tokens" value="ARRAY_DECLARATOR"/>
|
||||||
|
<property name="option" value="EOL"/>
|
||||||
|
</module>
|
||||||
|
<module name="SeparatorWrap">
|
||||||
|
<property name="id" value="SeparatorWrapMethodRef"/>
|
||||||
|
<property name="tokens" value="METHOD_REF"/>
|
||||||
|
<property name="option" value="nl"/>
|
||||||
|
</module>
|
||||||
|
<module name="PackageName">
|
||||||
|
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="TypeName">
|
||||||
|
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="MemberName">
|
||||||
|
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="ParameterName">
|
||||||
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="LambdaParameterName">
|
||||||
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="CatchParameterName">
|
||||||
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="LocalVariableName">
|
||||||
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="ClassTypeParameterName">
|
||||||
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="MethodTypeParameterName">
|
||||||
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="InterfaceTypeParameterName">
|
||||||
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="NoFinalizer"/>
|
||||||
|
<module name="GenericWhitespace">
|
||||||
|
<message key="ws.followed"
|
||||||
|
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||||
|
<message key="ws.preceded"
|
||||||
|
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||||
|
<message key="ws.illegalFollow"
|
||||||
|
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||||
|
<message key="ws.notPreceded"
|
||||||
|
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||||
|
</module>
|
||||||
|
<module name="Indentation">
|
||||||
|
<property name="basicOffset" value="4"/>
|
||||||
|
<property name="braceAdjustment" value="0"/>
|
||||||
|
<property name="caseIndent" value="4"/>
|
||||||
|
<property name="throwsIndent" value="4"/>
|
||||||
|
<property name="lineWrappingIndentation" value="4"/>
|
||||||
|
<property name="arrayInitIndent" value="4"/>
|
||||||
|
</module>
|
||||||
|
<module name="AbbreviationAsWordInName">
|
||||||
|
<property name="ignoreFinal" value="false"/>
|
||||||
|
<property name="allowedAbbreviationLength" value="1"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
|
||||||
|
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="OverloadMethodsDeclarationOrder"/>
|
||||||
|
<module name="VariableDeclarationUsageDistance"/>
|
||||||
|
<module name="CustomImportOrder">
|
||||||
|
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||||
|
<property name="separateLineBetweenGroups" value="true"/>
|
||||||
|
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
|
||||||
|
<property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="MethodParamPad">
|
||||||
|
<property name="tokens"
|
||||||
|
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
|
||||||
|
SUPER_CTOR_CALL, ENUM_CONSTANT_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="NoWhitespaceBefore">
|
||||||
|
<property name="tokens"
|
||||||
|
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS,
|
||||||
|
LABELED_STAT, METHOD_REF"/>
|
||||||
|
<property name="allowLineBreaks" value="true"/>
|
||||||
|
</module>
|
||||||
|
<module name="ParenPad">
|
||||||
|
<property name="tokens"
|
||||||
|
value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
|
||||||
|
EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
|
||||||
|
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
|
||||||
|
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA"/>
|
||||||
|
</module>
|
||||||
|
<module name="OperatorWrap">
|
||||||
|
<property name="option" value="NL"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
|
||||||
|
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF "/>
|
||||||
|
</module>
|
||||||
|
<module name="AnnotationLocation">
|
||||||
|
<property name="id" value="AnnotationLocationMostCases"/>
|
||||||
|
<property name="tokens"
|
||||||
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="AnnotationLocation">
|
||||||
|
<property name="id" value="AnnotationLocationVariables"/>
|
||||||
|
<property name="tokens" value="VARIABLE_DEF"/>
|
||||||
|
<property name="allowSamelineMultipleAnnotations" value="true"/>
|
||||||
|
</module>
|
||||||
|
<module name="NonEmptyAtclauseDescription"/>
|
||||||
|
<module name="InvalidJavadocPosition"/>
|
||||||
|
<module name="JavadocTagContinuationIndentation"/>
|
||||||
|
<module name="SummaryJavadoc">
|
||||||
|
<property name="forbiddenSummaryFragments"
|
||||||
|
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||||
|
</module>
|
||||||
|
<module name="JavadocParagraph"/>
|
||||||
|
<module name="AtclauseOrder">
|
||||||
|
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||||
|
<property name="target"
|
||||||
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="JavadocMethod">
|
||||||
|
<property name="scope" value="public"/>
|
||||||
|
<property name="allowMissingParamTags" value="true"/>
|
||||||
|
<property name="allowMissingReturnTag" value="true"/>
|
||||||
|
<property name="allowedAnnotations" value="Override, Test"/>
|
||||||
|
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="MissingJavadocMethod">
|
||||||
|
<property name="scope" value="public"/>
|
||||||
|
<property name="minLineCount" value="2"/>
|
||||||
|
<property name="allowedAnnotations" value="Override, Test"/>
|
||||||
|
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF"/>
|
||||||
|
</module>
|
||||||
|
<module name="MethodName">
|
||||||
|
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
|
||||||
|
<message key="name.invalidPattern"
|
||||||
|
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||||
|
</module>
|
||||||
|
<module name="SingleLineJavadoc">
|
||||||
|
<property name="ignoreInlineTags" value="false"/>
|
||||||
|
</module>
|
||||||
|
<module name="EmptyCatchBlock">
|
||||||
|
<property name="exceptionVariableName" value="expected"/>
|
||||||
|
</module>
|
||||||
|
<module name="CommentsIndentation">
|
||||||
|
<property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
|
||||||
|
</module>
|
||||||
|
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
|
||||||
|
<module name="SuppressionXpathFilter">
|
||||||
|
<property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
|
||||||
|
default="checkstyle-xpath-suppressions.xml" />
|
||||||
|
<property name="optional" value="true"/>
|
||||||
|
</module>
|
||||||
|
</module>
|
||||||
|
</module>
|
|
@ -28,8 +28,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
@SpringBootApplication(proxyBeanMethods = false)
|
@SpringBootApplication(proxyBeanMethods = false)
|
||||||
public class PetClinicApplication {
|
public class PetClinicApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(PetClinicApplication.class, args);
|
SpringApplication.run(PetClinicApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.model;
|
package org.springframework.samples.petclinic.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
@ -32,20 +32,20 @@ import javax.persistence.MappedSuperclass;
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public class BaseEntity implements Serializable {
|
public class BaseEntity implements Serializable {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Integer id) {
|
public void setId(Integer id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNew() {
|
public boolean isNew() {
|
||||||
return this.id == null;
|
return this.id == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.model;
|
package org.springframework.samples.petclinic.model;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
|
@ -28,20 +29,20 @@ import javax.persistence.MappedSuperclass;
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public class NamedEntity extends BaseEntity {
|
public class NamedEntity extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.getName();
|
return this.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.model;
|
package org.springframework.samples.petclinic.model;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
|
@ -27,28 +28,28 @@ import javax.validation.constraints.NotEmpty;
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public class Person extends BaseEntity {
|
public class Person extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "first_name")
|
@Column(name = "first_name")
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
private String firstName;
|
private String firstName;
|
||||||
|
|
||||||
@Column(name = "last_name")
|
@Column(name = "last_name")
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
return this.firstName;
|
return this.firstName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirstName(String firstName) {
|
public void setFirstName(String firstName) {
|
||||||
this.firstName = firstName;
|
this.firstName = firstName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLastName() {
|
public String getLastName() {
|
||||||
return this.lastName;
|
return this.lastName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastName(String lastName) {
|
public void setLastName(String lastName) {
|
||||||
this.lastName = lastName;
|
this.lastName = lastName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -20,7 +21,6 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
@ -28,7 +28,6 @@ import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.validation.constraints.Digits;
|
import javax.validation.constraints.Digits;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
import org.springframework.beans.support.MutableSortDefinition;
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
import org.springframework.beans.support.PropertyComparator;
|
||||||
import org.springframework.core.style.ToStringCreator;
|
import org.springframework.core.style.ToStringCreator;
|
||||||
|
@ -46,105 +45,118 @@ import org.springframework.samples.petclinic.model.Person;
|
||||||
@Table(name = "owners")
|
@Table(name = "owners")
|
||||||
public class Owner extends Person {
|
public class Owner extends Person {
|
||||||
|
|
||||||
@Column(name = "address")
|
@Column(name = "address")
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
@Column(name = "city")
|
@Column(name = "city")
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
private String city;
|
private String city;
|
||||||
|
|
||||||
@Column(name = "telephone")
|
@Column(name = "telephone")
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
@Digits(fraction = 0, integer = 10)
|
@Digits(fraction = 0, integer = 10)
|
||||||
private String telephone;
|
private String telephone;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
|
||||||
private Set<Pet> pets;
|
private Set<Pet> pets;
|
||||||
|
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return this.address;
|
return this.address;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAddress(String address) {
|
public void setAddress(String address) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCity() {
|
public String getCity() {
|
||||||
return this.city;
|
return this.city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCity(String city) {
|
public void setCity(String city) {
|
||||||
this.city = city;
|
this.city = city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTelephone() {
|
public String getTelephone() {
|
||||||
return this.telephone;
|
return this.telephone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTelephone(String telephone) {
|
public void setTelephone(String telephone) {
|
||||||
this.telephone = telephone;
|
this.telephone = telephone;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<Pet> getPetsInternal() {
|
protected Set<Pet> getPetsInternal() {
|
||||||
if (this.pets == null) {
|
if (this.pets == null) {
|
||||||
this.pets = new HashSet<>();
|
this.pets = new HashSet<>();
|
||||||
}
|
}
|
||||||
return this.pets;
|
return this.pets;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setPetsInternal(Set<Pet> pets) {
|
protected void setPetsInternal(Set<Pet> pets) {
|
||||||
this.pets = pets;
|
this.pets = pets;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pet> getPets() {
|
/**
|
||||||
List<Pet> sortedPets = new ArrayList<>(getPetsInternal());
|
* list of pets.
|
||||||
PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
|
*
|
||||||
return Collections.unmodifiableList(sortedPets);
|
* @return Returns list of pets.
|
||||||
}
|
*/
|
||||||
|
public List<Pet> getPets() {
|
||||||
|
List<Pet> sortedPets = new ArrayList<>(getPetsInternal());
|
||||||
|
PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
|
||||||
|
return Collections.unmodifiableList(sortedPets);
|
||||||
|
}
|
||||||
|
|
||||||
public void addPet(Pet pet) {
|
/**
|
||||||
if (pet.isNew()) {
|
* adds a pet.
|
||||||
getPetsInternal().add(pet);
|
*
|
||||||
}
|
* @param pet the pet to be added.
|
||||||
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.
|
* 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
|
* @param name to test
|
||||||
*/
|
* @return true if pet name is already in use
|
||||||
public Pet getPet(String name) {
|
*/
|
||||||
return getPet(name, false);
|
public Pet getPet(String name) {
|
||||||
}
|
return getPet(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the Pet with the given name, or null if none found for this Owner.
|
* 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
|
* @param name to test
|
||||||
*/
|
* @return true if pet name is already in use
|
||||||
public Pet getPet(String name, boolean ignoreNew) {
|
*/
|
||||||
name = name.toLowerCase();
|
public Pet getPet(String name, boolean ignoreNew) {
|
||||||
for (Pet pet : getPetsInternal()) {
|
name = name.toLowerCase();
|
||||||
if (!ignoreNew || !pet.isNew()) {
|
for (Pet pet : getPetsInternal()) {
|
||||||
String compName = pet.getName();
|
if (!ignoreNew || !pet.isNew()) {
|
||||||
compName = compName.toLowerCase();
|
String compName = pet.getName();
|
||||||
if (compName.equals(name)) {
|
compName = compName.toLowerCase();
|
||||||
return pet;
|
if (compName.equals(name)) {
|
||||||
}
|
return pet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringCreator(this)
|
return new ToStringCreator(this)
|
||||||
|
.append("id", this.getId()).append("new", this.isNew())
|
||||||
.append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName())
|
.append("lastName", this.getLastName())
|
||||||
.append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city)
|
.append("firstName", this.getFirstName()).append("address", this.address)
|
||||||
.append("telephone", this.telephone).toString();
|
.append("city", this.city)
|
||||||
}
|
.append("telephone", this.telephone).toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,12 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.validation.Valid;
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
import org.springframework.samples.petclinic.visit.VisitRepository;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
@ -26,11 +30,9 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Owner controller.
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Ken Krebs
|
* @author Ken Krebs
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
@ -39,107 +41,105 @@ import java.util.Map;
|
||||||
@Controller
|
@Controller
|
||||||
class OwnerController {
|
class OwnerController {
|
||||||
|
|
||||||
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
|
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM =
|
||||||
|
"owners/createOrUpdateOwnerForm";
|
||||||
|
|
||||||
private final OwnerRepository owners;
|
private final OwnerRepository owners;
|
||||||
|
|
||||||
private VisitRepository visits;
|
private final VisitRepository visits;
|
||||||
|
|
||||||
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
|
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
|
||||||
this.owners = clinicService;
|
this.owners = clinicService;
|
||||||
this.visits = visits;
|
this.visits = visits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder
|
@InitBinder
|
||||||
public void setAllowedFields(WebDataBinder dataBinder) {
|
public void setAllowedFields(WebDataBinder dataBinder) {
|
||||||
dataBinder.setDisallowedFields("id");
|
dataBinder.setDisallowedFields("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/owners/new")
|
@GetMapping("/owners/new")
|
||||||
public String initCreationForm(Map<String, Object> model) {
|
public String initCreationForm(Map<String, Object> model) {
|
||||||
Owner owner = new Owner();
|
Owner owner = new Owner();
|
||||||
model.put("owner", owner);
|
model.put("owner", owner);
|
||||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/owners/new")
|
@PostMapping("/owners/new")
|
||||||
public String processCreationForm(@Valid Owner owner, BindingResult result) {
|
public String processCreationForm(@Valid Owner owner, BindingResult result) {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
} else {
|
||||||
else {
|
this.owners.save(owner);
|
||||||
this.owners.save(owner);
|
return "redirect:/owners/" + owner.getId();
|
||||||
return "redirect:/owners/" + owner.getId();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/owners/find")
|
@GetMapping("/owners/find")
|
||||||
public String initFindForm(Map<String, Object> model) {
|
public String initFindForm(Map<String, Object> model) {
|
||||||
model.put("owner", new Owner());
|
model.put("owner", new Owner());
|
||||||
return "owners/findOwners";
|
return "owners/findOwners";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/owners")
|
@GetMapping("/owners")
|
||||||
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> model) {
|
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> model) {
|
||||||
|
|
||||||
// allow parameterless GET request for /owners to return all records
|
// allow parameterless GET request for /owners to return all records
|
||||||
if (owner.getLastName() == null) {
|
if (owner.getLastName() == null) {
|
||||||
owner.setLastName(""); // empty string signifies broadest possible search
|
owner.setLastName(""); // empty string signifies broadest possible search
|
||||||
}
|
}
|
||||||
|
|
||||||
// find owners by last name
|
// find owners by last name
|
||||||
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
|
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
// no owners found
|
// no owners found
|
||||||
result.rejectValue("lastName", "notFound", "not found");
|
result.rejectValue("lastName", "notFound", "not found");
|
||||||
return "owners/findOwners";
|
return "owners/findOwners";
|
||||||
}
|
} else if (results.size() == 1) {
|
||||||
else if (results.size() == 1) {
|
// 1 owner found
|
||||||
// 1 owner found
|
owner = results.iterator().next();
|
||||||
owner = results.iterator().next();
|
return "redirect:/owners/" + owner.getId();
|
||||||
return "redirect:/owners/" + owner.getId();
|
} else {
|
||||||
}
|
// multiple owners found
|
||||||
else {
|
model.put("selections", results);
|
||||||
// multiple owners found
|
return "owners/ownersList";
|
||||||
model.put("selections", results);
|
}
|
||||||
return "owners/ownersList";
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/owners/{ownerId}/edit")
|
@GetMapping("/owners/{ownerId}/edit")
|
||||||
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
|
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
|
||||||
Owner owner = this.owners.findById(ownerId);
|
Owner owner = this.owners.findById(ownerId);
|
||||||
model.addAttribute(owner);
|
model.addAttribute(owner);
|
||||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/owners/{ownerId}/edit")
|
@PostMapping("/owners/{ownerId}/edit")
|
||||||
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result,
|
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result,
|
||||||
@PathVariable("ownerId") int ownerId) {
|
@PathVariable("ownerId") int ownerId) {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
} else {
|
||||||
else {
|
owner.setId(ownerId);
|
||||||
owner.setId(ownerId);
|
this.owners.save(owner);
|
||||||
this.owners.save(owner);
|
return "redirect:/owners/{ownerId}";
|
||||||
return "redirect:/owners/{ownerId}";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom handler for displaying an owner.
|
* 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
|
* @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) {
|
@GetMapping("/owners/{ownerId}")
|
||||||
ModelAndView mav = new ModelAndView("owners/ownerDetails");
|
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
|
||||||
Owner owner = this.owners.findById(ownerId);
|
ModelAndView mav = new ModelAndView("owners/ownerDetails");
|
||||||
for (Pet pet : owner.getPets()) {
|
Owner owner = this.owners.findById(ownerId);
|
||||||
pet.setVisitsInternal(visits.findByPetId(pet.getId()));
|
for (Pet pet : owner.getPets()) {
|
||||||
}
|
pet.setVisitsInternal(visits.findByPetId(pet.getId()));
|
||||||
mav.addObject(owner);
|
}
|
||||||
return mav;
|
mav.addObject(owner);
|
||||||
}
|
return mav;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
@ -35,30 +35,32 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
*/
|
*/
|
||||||
public interface OwnerRepository extends Repository<Owner, Integer> {
|
public interface OwnerRepository extends Repository<Owner, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve {@link Owner}s from the data store by last name, returning all owners
|
* Retrieve {@link Owner}s from the data store by last name, returning all owners
|
||||||
* whose last name <i>starts</i> with the given name.
|
* whose last name <i>starts</i> with the given name.
|
||||||
* @param lastName Value to search for
|
*
|
||||||
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
|
* @param lastName Value to search for
|
||||||
* found)
|
* @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%")
|
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
Collection<Owner> findByLastName(@Param("lastName") String lastName);
|
Collection<Owner> findByLastName(@Param("lastName") String lastName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve an {@link Owner} from the data store by id.
|
* Retrieve an {@link Owner} from the data store by id.
|
||||||
* @param id the id to search for
|
*
|
||||||
* @return the {@link Owner} if found
|
* @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)
|
@Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
|
||||||
Owner findById(@Param("id") Integer id);
|
@Transactional(readOnly = true)
|
||||||
|
Owner findById(@Param("id") Integer id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save an {@link Owner} to the data store, either inserting or updating it.
|
* Save an {@link Owner} to the data store, either inserting or updating it.
|
||||||
* @param owner the {@link Owner} to save
|
*
|
||||||
*/
|
* @param owner the {@link Owner} to save
|
||||||
void save(Owner owner);
|
*/
|
||||||
|
void save(Owner owner);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
@ -23,14 +24,12 @@ import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
import org.springframework.beans.support.MutableSortDefinition;
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
import org.springframework.beans.support.PropertyComparator;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
@ -48,65 +47,75 @@ import org.springframework.samples.petclinic.visit.Visit;
|
||||||
@Table(name = "pets")
|
@Table(name = "pets")
|
||||||
public class Pet extends NamedEntity {
|
public class Pet extends NamedEntity {
|
||||||
|
|
||||||
@Column(name = "birth_date")
|
@Column(name = "birth_date")
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDate birthDate;
|
private LocalDate birthDate;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "type_id")
|
@JoinColumn(name = "type_id")
|
||||||
private PetType type;
|
private PetType type;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "owner_id")
|
@JoinColumn(name = "owner_id")
|
||||||
private Owner owner;
|
private Owner owner;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private Set<Visit> visits = new LinkedHashSet<>();
|
private Set<Visit> visits = new LinkedHashSet<>();
|
||||||
|
|
||||||
public void setBirthDate(LocalDate birthDate) {
|
public void setBirthDate(LocalDate birthDate) {
|
||||||
this.birthDate = birthDate;
|
this.birthDate = birthDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getBirthDate() {
|
public LocalDate getBirthDate() {
|
||||||
return this.birthDate;
|
return this.birthDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PetType getType() {
|
public PetType getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(PetType type) {
|
public void setType(PetType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Owner getOwner() {
|
public Owner getOwner() {
|
||||||
return this.owner;
|
return this.owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setOwner(Owner owner) {
|
protected void setOwner(Owner owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<Visit> getVisitsInternal() {
|
protected Set<Visit> getVisitsInternal() {
|
||||||
if (this.visits == null) {
|
if (this.visits == null) {
|
||||||
this.visits = new HashSet<>();
|
this.visits = new HashSet<>();
|
||||||
}
|
}
|
||||||
return this.visits;
|
return this.visits;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setVisitsInternal(Collection<Visit> visits) {
|
protected void setVisitsInternal(Collection<Visit> visits) {
|
||||||
this.visits = new LinkedHashSet<>(visits);
|
this.visits = new LinkedHashSet<>(visits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Visit> getVisits() {
|
/**
|
||||||
List<Visit> sortedVisits = new ArrayList<>(getVisitsInternal());
|
* list of visits.
|
||||||
PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
|
*
|
||||||
return Collections.unmodifiableList(sortedVisits);
|
* @return list of visits
|
||||||
}
|
*/
|
||||||
|
public List<Visit> getVisits() {
|
||||||
|
List<Visit> sortedVisits = new ArrayList<>(getVisitsInternal());
|
||||||
|
PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
|
||||||
|
return Collections.unmodifiableList(sortedVisits);
|
||||||
|
}
|
||||||
|
|
||||||
public void addVisit(Visit visit) {
|
/**
|
||||||
getVisitsInternal().add(visit);
|
* add a visit to list.
|
||||||
visit.setPetId(this.getId());
|
*
|
||||||
}
|
* @param visit the visit to add.
|
||||||
|
*/
|
||||||
|
public void addVisit(Visit visit) {
|
||||||
|
getVisitsInternal().add(visit);
|
||||||
|
visit.setPetId(this.getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,19 +13,26 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.validation.Valid;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import javax.validation.Valid;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import java.util.Collection;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Pet controller.
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Ken Krebs
|
* @author Ken Krebs
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
@ -34,80 +41,78 @@ import java.util.Collection;
|
||||||
@RequestMapping("/owners/{ownerId}")
|
@RequestMapping("/owners/{ownerId}")
|
||||||
class PetController {
|
class PetController {
|
||||||
|
|
||||||
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
|
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
|
||||||
|
|
||||||
private final PetRepository pets;
|
private final PetRepository pets;
|
||||||
|
|
||||||
private final OwnerRepository owners;
|
private final OwnerRepository owners;
|
||||||
|
|
||||||
public PetController(PetRepository pets, OwnerRepository owners) {
|
public PetController(PetRepository pets, OwnerRepository owners) {
|
||||||
this.pets = pets;
|
this.pets = pets;
|
||||||
this.owners = owners;
|
this.owners = owners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModelAttribute("types")
|
@ModelAttribute("types")
|
||||||
public Collection<PetType> populatePetTypes() {
|
public Collection<PetType> populatePetTypes() {
|
||||||
return this.pets.findPetTypes();
|
return this.pets.findPetTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModelAttribute("owner")
|
@ModelAttribute("owner")
|
||||||
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
||||||
return this.owners.findById(ownerId);
|
return this.owners.findById(ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder("owner")
|
@InitBinder("owner")
|
||||||
public void initOwnerBinder(WebDataBinder dataBinder) {
|
public void initOwnerBinder(WebDataBinder dataBinder) {
|
||||||
dataBinder.setDisallowedFields("id");
|
dataBinder.setDisallowedFields("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder("pet")
|
@InitBinder("pet")
|
||||||
public void initPetBinder(WebDataBinder dataBinder) {
|
public void initPetBinder(WebDataBinder dataBinder) {
|
||||||
dataBinder.setValidator(new PetValidator());
|
dataBinder.setValidator(new PetValidator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/pets/new")
|
@GetMapping("/pets/new")
|
||||||
public String initCreationForm(Owner owner, ModelMap model) {
|
public String initCreationForm(Owner owner, ModelMap model) {
|
||||||
Pet pet = new Pet();
|
Pet pet = new Pet();
|
||||||
owner.addPet(pet);
|
owner.addPet(pet);
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/pets/new")
|
@PostMapping("/pets/new")
|
||||||
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
|
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) {
|
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
|
||||||
result.rejectValue("name", "duplicate", "already exists");
|
result.rejectValue("name", "duplicate", "already exists");
|
||||||
}
|
}
|
||||||
owner.addPet(pet);
|
owner.addPet(pet);
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
} else {
|
||||||
else {
|
this.pets.save(pet);
|
||||||
this.pets.save(pet);
|
return "redirect:/owners/{ownerId}";
|
||||||
return "redirect:/owners/{ownerId}";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/pets/{petId}/edit")
|
@GetMapping("/pets/{petId}/edit")
|
||||||
public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
|
public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
|
||||||
Pet pet = this.pets.findById(petId);
|
Pet pet = this.pets.findById(petId);
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/pets/{petId}/edit")
|
@PostMapping("/pets/{petId}/edit")
|
||||||
public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
|
public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
pet.setOwner(owner);
|
pet.setOwner(owner);
|
||||||
model.put("pet", pet);
|
model.put("pet", pet);
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
} else {
|
||||||
else {
|
owner.addPet(pet);
|
||||||
owner.addPet(pet);
|
this.pets.save(pet);
|
||||||
this.pets.save(pet);
|
return "redirect:/owners/{ownerId}";
|
||||||
return "redirect:/owners/{ownerId}";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -34,26 +34,29 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
*/
|
*/
|
||||||
public interface PetRepository extends Repository<Pet, Integer> {
|
public interface PetRepository extends Repository<Pet, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all {@link PetType}s from the data store.
|
* Retrieve all {@link PetType}s from the data store.
|
||||||
* @return a Collection of {@link PetType}s.
|
*
|
||||||
*/
|
* @return a Collection of {@link PetType}s.
|
||||||
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
|
||||||
List<PetType> findPetTypes();
|
@Transactional(readOnly = true)
|
||||||
|
List<PetType> findPetTypes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a {@link Pet} from the data store by id.
|
* Retrieve a {@link Pet} from the data store by id.
|
||||||
* @param id the id to search for
|
*
|
||||||
* @return the {@link Pet} if found
|
* @param id the id to search for
|
||||||
*/
|
* @return the {@link Pet} if found
|
||||||
@Transactional(readOnly = true)
|
*/
|
||||||
Pet findById(Integer id);
|
@Transactional(readOnly = true)
|
||||||
|
Pet findById(Integer id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a {@link Pet} to the data store, either inserting or updating it.
|
* Save a {@link Pet} to the data store, either inserting or updating it.
|
||||||
* @param pet the {@link Pet} to save
|
*
|
||||||
*/
|
* @param pet the {@link Pet} to save
|
||||||
void save(Pet pet);
|
*/
|
||||||
|
void save(Pet pet);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,16 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Pet type.
|
||||||
|
*
|
||||||
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
|
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.format.Formatter;
|
import org.springframework.format.Formatter;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -36,27 +36,27 @@ import org.springframework.stereotype.Component;
|
||||||
@Component
|
@Component
|
||||||
public class PetTypeFormatter implements Formatter<PetType> {
|
public class PetTypeFormatter implements Formatter<PetType> {
|
||||||
|
|
||||||
private final PetRepository pets;
|
private final PetRepository pets;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PetTypeFormatter(PetRepository pets) {
|
public PetTypeFormatter(PetRepository pets) {
|
||||||
this.pets = pets;
|
this.pets = pets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String print(PetType petType, Locale locale) {
|
public String print(PetType petType, Locale locale) {
|
||||||
return petType.getName();
|
return petType.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PetType parse(String text, Locale locale) throws ParseException {
|
public PetType parse(String text, Locale locale) throws ParseException {
|
||||||
Collection<PetType> findPetTypes = this.pets.findPetTypes();
|
Collection<PetType> findPetTypes = this.pets.findPetTypes();
|
||||||
for (PetType type : findPetTypes) {
|
for (PetType type : findPetTypes) {
|
||||||
if (type.getName().equals(text)) {
|
if (type.getName().equals(text)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ParseException("type not found: " + text, 0);
|
throw new ParseException("type not found: " + text, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -31,34 +32,34 @@ import org.springframework.validation.Validator;
|
||||||
*/
|
*/
|
||||||
public class PetValidator implements Validator {
|
public class PetValidator implements Validator {
|
||||||
|
|
||||||
private static final String REQUIRED = "required";
|
private static final String REQUIRED = "required";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate(Object obj, Errors errors) {
|
public void validate(Object obj, Errors errors) {
|
||||||
Pet pet = (Pet) obj;
|
Pet pet = (Pet) obj;
|
||||||
String name = pet.getName();
|
String name = pet.getName();
|
||||||
// name validation
|
// name validation
|
||||||
if (!StringUtils.hasLength(name)) {
|
if (!StringUtils.hasLength(name)) {
|
||||||
errors.rejectValue("name", REQUIRED, REQUIRED);
|
errors.rejectValue("name", REQUIRED, REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// type validation
|
// type validation
|
||||||
if (pet.isNew() && pet.getType() == null) {
|
if (pet.isNew() && pet.getType() == null) {
|
||||||
errors.rejectValue("type", REQUIRED, REQUIRED);
|
errors.rejectValue("type", REQUIRED, REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// birth date validation
|
// birth date validation
|
||||||
if (pet.getBirthDate() == null) {
|
if (pet.getBirthDate() == null) {
|
||||||
errors.rejectValue("birthDate", REQUIRED, REQUIRED);
|
errors.rejectValue("birthDate", REQUIRED, REQUIRED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Validator validates *just* Pet instances
|
* This Validator validates *just* Pet instances.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Class<?> clazz) {
|
public boolean supports(Class<?> clazz) {
|
||||||
return Pet.class.isAssignableFrom(clazz);
|
return Pet.class.isAssignableFrom(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.visit.Visit;
|
import org.springframework.samples.petclinic.visit.Visit;
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
import org.springframework.samples.petclinic.visit.VisitRepository;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -31,6 +30,8 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Visit controller.
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Ken Krebs
|
* @author Ken Krebs
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
@ -40,53 +41,53 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@Controller
|
@Controller
|
||||||
class VisitController {
|
class VisitController {
|
||||||
|
|
||||||
private final VisitRepository visits;
|
private final VisitRepository visits;
|
||||||
|
|
||||||
private final PetRepository pets;
|
private final PetRepository pets;
|
||||||
|
|
||||||
public VisitController(VisitRepository visits, PetRepository pets) {
|
public VisitController(VisitRepository visits, PetRepository pets) {
|
||||||
this.visits = visits;
|
this.visits = visits;
|
||||||
this.pets = pets;
|
this.pets = pets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder
|
@InitBinder
|
||||||
public void setAllowedFields(WebDataBinder dataBinder) {
|
public void setAllowedFields(WebDataBinder dataBinder) {
|
||||||
dataBinder.setDisallowedFields("id");
|
dataBinder.setDisallowedFields("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before each and every @RequestMapping annotated method. 2 goals: - Make sure
|
* 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
|
* 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)
|
* Pet object always has an id (Even though id is not part of the form fields)
|
||||||
* @param petId
|
*
|
||||||
* @return Pet
|
* @param petId the pete id
|
||||||
*/
|
* @return Pet the visit.
|
||||||
@ModelAttribute("visit")
|
*/
|
||||||
public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map<String, Object> model) {
|
@ModelAttribute("visit")
|
||||||
Pet pet = this.pets.findById(petId);
|
public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map<String, Object> model) {
|
||||||
pet.setVisitsInternal(this.visits.findByPetId(petId));
|
Pet pet = this.pets.findById(petId);
|
||||||
model.put("pet", pet);
|
pet.setVisitsInternal(this.visits.findByPetId(petId));
|
||||||
Visit visit = new Visit();
|
model.put("pet", pet);
|
||||||
pet.addVisit(visit);
|
Visit visit = new Visit();
|
||||||
return visit;
|
pet.addVisit(visit);
|
||||||
}
|
return visit;
|
||||||
|
}
|
||||||
|
|
||||||
// Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
|
// Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
|
||||||
@GetMapping("/owners/*/pets/{petId}/visits/new")
|
@GetMapping("/owners/*/pets/{petId}/visits/new")
|
||||||
public String initNewVisitForm(@PathVariable("petId") int petId, Map<String, Object> model) {
|
public String initNewVisitForm(@PathVariable("petId") int petId, Map<String, Object> model) {
|
||||||
return "pets/createOrUpdateVisitForm";
|
return "pets/createOrUpdateVisitForm";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
|
// Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
|
||||||
@PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
|
@PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
|
||||||
public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
|
public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return "pets/createOrUpdateVisitForm";
|
return "pets/createOrUpdateVisitForm";
|
||||||
}
|
} else {
|
||||||
else {
|
this.visits.save(visit);
|
||||||
this.visits.save(visit);
|
return "redirect:/owners/{ownerId}";
|
||||||
return "redirect:/owners/{ownerId}";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package org.springframework.samples.petclinic.system;
|
package org.springframework.samples.petclinic.system;
|
||||||
|
|
||||||
import javax.cache.configuration.MutableConfiguration;
|
import javax.cache.configuration.MutableConfiguration;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
|
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
@ -32,24 +31,24 @@ import org.springframework.context.annotation.Configuration;
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
class CacheConfiguration {
|
class CacheConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
|
public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
|
||||||
return cm -> {
|
return cm -> {
|
||||||
cm.createCache("vets", cacheConfiguration());
|
cm.createCache("vets", cacheConfiguration());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a simple configuration that enable statistics via the JCache programmatic
|
* Create a simple configuration that enable statistics via the JCache programmatic
|
||||||
* configuration API.
|
* configuration API.
|
||||||
* <p>
|
*
|
||||||
* Within the configuration object that is provided by the JCache API standard, there
|
* <p>Within the configuration object that is provided by the JCache API standard, there
|
||||||
* is only a very limited set of configuration options. The really relevant
|
* is only a very limited set of configuration options. The really relevant
|
||||||
* configuration options (like the size limit) must be set via a configuration
|
* configuration options (like the size limit) must be set via a configuration
|
||||||
* mechanism that is provided by the selected JCache implementation.
|
* mechanism that is provided by the selected JCache implementation.
|
||||||
*/
|
*/
|
||||||
private javax.cache.configuration.Configuration<Object, Object> cacheConfiguration() {
|
private javax.cache.configuration.Configuration<Object, Object> cacheConfiguration() {
|
||||||
return new MutableConfiguration<>().setStatisticsEnabled(true);
|
return new MutableConfiguration<>().setStatisticsEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,26 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.system;
|
package org.springframework.samples.petclinic.system;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller used to showcase what happens when an exception is thrown
|
* Controller used to showcase what happens when an exception is thrown.
|
||||||
*
|
*
|
||||||
* @author Michael Isvy
|
* @author Michael Isvy
|
||||||
* <p/>
|
*
|
||||||
* Also see how a view that resolves to "error" has been added ("error.html").
|
* <p/>Also see how a view that resolves to "error" has been added ("error.html").
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
class CrashController {
|
class CrashController {
|
||||||
|
|
||||||
@GetMapping("/oups")
|
@GetMapping("/oups")
|
||||||
public String triggerException() {
|
public String triggerException() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"Expected: controller used to showcase what " + "happens when an exception is thrown");
|
"Expected: controller used to showcase what " + "happens when an exception is thrown");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@Controller
|
@Controller
|
||||||
class WelcomeController {
|
class WelcomeController {
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String welcome() {
|
public String welcome() {
|
||||||
return "welcome";
|
return "welcome";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,12 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -20,7 +21,6 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
|
@ -28,7 +28,6 @@ import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToMany;
|
import javax.persistence.ManyToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
import org.springframework.beans.support.MutableSortDefinition;
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
import org.springframework.beans.support.PropertyComparator;
|
||||||
import org.springframework.samples.petclinic.model.Person;
|
import org.springframework.samples.petclinic.model.Person;
|
||||||
|
@ -45,35 +44,44 @@ import org.springframework.samples.petclinic.model.Person;
|
||||||
@Table(name = "vets")
|
@Table(name = "vets")
|
||||||
public class Vet extends Person {
|
public class Vet extends Person {
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER)
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
|
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "specialty_id"))
|
inverseJoinColumns = @JoinColumn(name = "specialty_id"))
|
||||||
private Set<Specialty> specialties;
|
private Set<Specialty> specialties;
|
||||||
|
|
||||||
protected Set<Specialty> getSpecialtiesInternal() {
|
protected Set<Specialty> getSpecialtiesInternal() {
|
||||||
if (this.specialties == null) {
|
if (this.specialties == null) {
|
||||||
this.specialties = new HashSet<>();
|
this.specialties = new HashSet<>();
|
||||||
}
|
}
|
||||||
return this.specialties;
|
return this.specialties;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setSpecialtiesInternal(Set<Specialty> specialties) {
|
protected void setSpecialtiesInternal(Set<Specialty> specialties) {
|
||||||
this.specialties = specialties;
|
this.specialties = specialties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@XmlElement
|
/**
|
||||||
public List<Specialty> getSpecialties() {
|
* gets list of specialties.
|
||||||
List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
|
*/
|
||||||
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
|
@XmlElement
|
||||||
return Collections.unmodifiableList(sortedSpecs);
|
public List<Specialty> getSpecialties() {
|
||||||
}
|
List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
|
||||||
|
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
|
||||||
|
return Collections.unmodifiableList(sortedSpecs);
|
||||||
|
}
|
||||||
|
|
||||||
public int getNrOfSpecialties() {
|
/**
|
||||||
return getSpecialtiesInternal().size();
|
* number of specialties.
|
||||||
}
|
*/
|
||||||
|
public int getNrOfSpecialties() {
|
||||||
|
return getSpecialtiesInternal().size();
|
||||||
|
}
|
||||||
|
|
||||||
public void addSpecialty(Specialty specialty) {
|
/**
|
||||||
getSpecialtiesInternal().add(specialty);
|
* Add a specialty.
|
||||||
}
|
*/
|
||||||
|
public void addSpecialty(Specialty specialty) {
|
||||||
|
getSpecialtiesInternal().add(specialty);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,17 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Vet Controller.
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @author Ken Krebs
|
* @author Ken Krebs
|
||||||
|
@ -30,29 +32,29 @@ import java.util.Map;
|
||||||
@Controller
|
@Controller
|
||||||
class VetController {
|
class VetController {
|
||||||
|
|
||||||
private final VetRepository vets;
|
private final VetRepository vets;
|
||||||
|
|
||||||
public VetController(VetRepository clinicService) {
|
public VetController(VetRepository clinicService) {
|
||||||
this.vets = clinicService;
|
this.vets = clinicService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/vets.html")
|
@GetMapping("/vets.html")
|
||||||
public String showVetList(Map<String, Object> model) {
|
public String showVetList(Map<String, Object> model) {
|
||||||
// Here we are returning an object of type 'Vets' rather than a collection of Vet
|
// Here we are returning an object of type 'Vets' rather than a collection of Vet
|
||||||
// objects so it is simpler for Object-Xml mapping
|
// objects so it is simpler for Object-Xml mapping
|
||||||
Vets vets = new Vets();
|
Vets vets = new Vets();
|
||||||
vets.getVetList().addAll(this.vets.findAll());
|
vets.getVetList().addAll(this.vets.findAll());
|
||||||
model.put("vets", vets);
|
model.put("vets", vets);
|
||||||
return "vets/vetList";
|
return "vets/vetList";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping({ "/vets" })
|
@GetMapping({"/vets"})
|
||||||
public @ResponseBody Vets showResourcesVetList() {
|
public @ResponseBody Vets showResourcesVetList() {
|
||||||
// Here we are returning an object of type 'Vets' rather than a collection of Vet
|
// Here we are returning an object of type 'Vets' rather than a collection of Vet
|
||||||
// objects so it is simpler for JSon/Object mapping
|
// objects so it is simpler for JSon/Object mapping
|
||||||
Vets vets = new Vets();
|
Vets vets = new Vets();
|
||||||
vets.getVetList().addAll(this.vets.findAll());
|
vets.getVetList().addAll(this.vets.findAll());
|
||||||
return vets;
|
return vets;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
|
@ -35,12 +35,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
*/
|
*/
|
||||||
public interface VetRepository extends Repository<Vet, Integer> {
|
public interface VetRepository extends Repository<Vet, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all <code>Vet</code>s from the data store.
|
* Retrieve all <code>Vet</code>s from the data store.
|
||||||
* @return a <code>Collection</code> of <code>Vet</code>s
|
*
|
||||||
*/
|
* @return a <code>Collection</code> of <code>Vet</code>s
|
||||||
@Transactional(readOnly = true)
|
*/
|
||||||
@Cacheable("vets")
|
@Transactional(readOnly = true)
|
||||||
Collection<Vet> findAll() throws DataAccessException;
|
@Cacheable("vets")
|
||||||
|
Collection<Vet> findAll() throws DataAccessException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@ -30,14 +30,16 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
@XmlRootElement
|
@XmlRootElement
|
||||||
public class Vets {
|
public class Vets {
|
||||||
|
|
||||||
private List<Vet> vets;
|
private List<Vet> vets;
|
||||||
|
|
||||||
@XmlElement
|
/**
|
||||||
public List<Vet> getVetList() {
|
* returns all Vets.
|
||||||
if (vets == null) {
|
*/
|
||||||
vets = new ArrayList<>();
|
@XmlElement public List<Vet> getVetList() {
|
||||||
}
|
if (vets == null) {
|
||||||
return vets;
|
vets = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
return vets;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.visit;
|
package org.springframework.samples.petclinic.visit;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
|
|
||||||
|
@ -35,46 +34,46 @@ import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
@Table(name = "visits")
|
@Table(name = "visits")
|
||||||
public class Visit extends BaseEntity {
|
public class Visit extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "visit_date")
|
@Column(name = "visit_date")
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
@Column(name = "description")
|
@Column(name = "description")
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
@Column(name = "pet_id")
|
@Column(name = "pet_id")
|
||||||
private Integer petId;
|
private Integer petId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of Visit for the current date
|
* Creates a new instance of Visit for the current date.
|
||||||
*/
|
*/
|
||||||
public Visit() {
|
public Visit() {
|
||||||
this.date = LocalDate.now();
|
this.date = LocalDate.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getDate() {
|
public LocalDate getDate() {
|
||||||
return this.date;
|
return this.date;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDate(LocalDate date) {
|
public void setDate(LocalDate date) {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return this.description;
|
return this.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getPetId() {
|
public Integer getPetId() {
|
||||||
return this.petId;
|
return this.petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPetId(Integer petId) {
|
public void setPetId(Integer petId) {
|
||||||
this.petId = petId;
|
this.petId = petId;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.visit;
|
package org.springframework.samples.petclinic.visit;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
|
@ -34,13 +34,14 @@ import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
*/
|
*/
|
||||||
public interface VisitRepository extends Repository<Visit, Integer> {
|
public interface VisitRepository extends Repository<Visit, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a <code>Visit</code> to the data store, either inserting or updating it.
|
* Save a <code>Visit</code> to the data store, either inserting or updating it.
|
||||||
* @param visit the <code>Visit</code> to save
|
*
|
||||||
* @see BaseEntity#isNew
|
* @param visit the <code>Visit</code> to save
|
||||||
*/
|
* @see BaseEntity#isNew
|
||||||
void save(Visit visit) throws DataAccessException;
|
*/
|
||||||
|
void save(Visit visit) throws DataAccessException;
|
||||||
|
|
||||||
List<Visit> findByPetId(Integer petId);
|
List<Visit> findByPetId(Integer petId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,13 @@ import org.springframework.samples.petclinic.vet.VetRepository;
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class PetclinicIntegrationTests {
|
class PetclinicIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private VetRepository vets;
|
private VetRepository vets;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFindAll() throws Exception {
|
void testFindAll() throws Exception {
|
||||||
vets.findAll();
|
vets.findAll();
|
||||||
vets.findAll(); // served from cache
|
vets.findAll(); // served from cache
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,45 +16,43 @@
|
||||||
|
|
||||||
package org.springframework.samples.petclinic.model;
|
package org.springframework.samples.petclinic.model;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.validation.ConstraintViolation;
|
import javax.validation.ConstraintViolation;
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.context.i18n.LocaleContextHolder;
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Isvy Simple test to make sure that Bean Validation is working (useful
|
* @author Michael Isvy Simple test to make sure that Bean Validation is working (useful
|
||||||
* when upgrading to a new version of Hibernate Validator/ Bean Validation)
|
* when upgrading to a new version of Hibernate Validator/ Bean Validation)
|
||||||
*/
|
*/
|
||||||
class ValidatorTests {
|
class ValidatorTests {
|
||||||
|
|
||||||
private Validator createValidator() {
|
private Validator createValidator() {
|
||||||
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
|
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
|
||||||
localValidatorFactoryBean.afterPropertiesSet();
|
localValidatorFactoryBean.afterPropertiesSet();
|
||||||
return localValidatorFactoryBean;
|
return localValidatorFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldNotValidateWhenFirstNameEmpty() {
|
void shouldNotValidateWhenFirstNameEmpty() {
|
||||||
|
|
||||||
LocaleContextHolder.setLocale(Locale.ENGLISH);
|
LocaleContextHolder.setLocale(Locale.ENGLISH);
|
||||||
Person person = new Person();
|
Person person = new Person();
|
||||||
person.setFirstName("");
|
person.setFirstName("");
|
||||||
person.setLastName("smith");
|
person.setLastName("smith");
|
||||||
|
|
||||||
Validator validator = createValidator();
|
Validator validator = createValidator();
|
||||||
Set<ConstraintViolation<Person>> constraintViolations = validator.validate(person);
|
Set<ConstraintViolation<Person>> constraintViolations = validator.validate(person);
|
||||||
|
|
||||||
assertThat(constraintViolations).hasSize(1);
|
assertThat(constraintViolations).hasSize(1);
|
||||||
ConstraintViolation<Person> violation = constraintViolations.iterator().next();
|
ConstraintViolation<Person> violation = constraintViolations.iterator().next();
|
||||||
assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName");
|
assertThat(violation.getPropertyPath().toString()).isEqualTo("firstName");
|
||||||
assertThat(violation.getMessage()).isEqualTo("must not be empty");
|
assertThat(violation.getMessage()).isEqualTo("must not be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,149 +51,149 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@WebMvcTest(OwnerController.class)
|
@WebMvcTest(OwnerController.class)
|
||||||
class OwnerControllerTests {
|
class OwnerControllerTests {
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
private static final int TEST_OWNER_ID = 1;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private OwnerRepository owners;
|
private OwnerRepository owners;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private VisitRepository visits;
|
private VisitRepository visits;
|
||||||
|
|
||||||
private Owner george;
|
private Owner george;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
george = new Owner();
|
george = new Owner();
|
||||||
george.setId(TEST_OWNER_ID);
|
george.setId(TEST_OWNER_ID);
|
||||||
george.setFirstName("George");
|
george.setFirstName("George");
|
||||||
george.setLastName("Franklin");
|
george.setLastName("Franklin");
|
||||||
george.setAddress("110 W. Liberty St.");
|
george.setAddress("110 W. Liberty St.");
|
||||||
george.setCity("Madison");
|
george.setCity("Madison");
|
||||||
george.setTelephone("6085551023");
|
george.setTelephone("6085551023");
|
||||||
Pet max = new Pet();
|
Pet max = new Pet();
|
||||||
PetType dog = new PetType();
|
PetType dog = new PetType();
|
||||||
dog.setName("dog");
|
dog.setName("dog");
|
||||||
max.setId(1);
|
max.setId(1);
|
||||||
max.setType(dog);
|
max.setType(dog);
|
||||||
max.setName("Max");
|
max.setName("Max");
|
||||||
max.setBirthDate(LocalDate.now());
|
max.setBirthDate(LocalDate.now());
|
||||||
george.setPetsInternal(Collections.singleton(max));
|
george.setPetsInternal(Collections.singleton(max));
|
||||||
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
|
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
|
||||||
Visit visit = new Visit();
|
Visit visit = new Visit();
|
||||||
visit.setDate(LocalDate.now());
|
visit.setDate(LocalDate.now());
|
||||||
given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit));
|
given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitCreationForm() throws Exception {
|
void testInitCreationForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
|
mockMvc.perform(get("/owners/new")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
|
||||||
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessCreationFormSuccess() throws Exception {
|
void testProcessCreationFormSuccess() throws Exception {
|
||||||
mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs")
|
mockMvc.perform(post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs")
|
||||||
.param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638"))
|
.param("address", "123 Caramel Street").param("city", "London").param("telephone", "01316761638"))
|
||||||
.andExpect(status().is3xxRedirection());
|
.andExpect(status().is3xxRedirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessCreationFormHasErrors() throws Exception {
|
void testProcessCreationFormHasErrors() throws Exception {
|
||||||
mockMvc.perform(
|
mockMvc.perform(
|
||||||
post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London"))
|
post("/owners/new").param("firstName", "Joe").param("lastName", "Bloggs").param("city", "London"))
|
||||||
.andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner"))
|
.andExpect(status().isOk()).andExpect(model().attributeHasErrors("owner"))
|
||||||
.andExpect(model().attributeHasFieldErrors("owner", "address"))
|
.andExpect(model().attributeHasFieldErrors("owner", "address"))
|
||||||
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
|
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
|
||||||
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitFindForm() throws Exception {
|
void testInitFindForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
|
mockMvc.perform(get("/owners/find")).andExpect(status().isOk()).andExpect(model().attributeExists("owner"))
|
||||||
.andExpect(view().name("owners/findOwners"));
|
.andExpect(view().name("owners/findOwners"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessFindFormSuccess() throws Exception {
|
void testProcessFindFormSuccess() throws Exception {
|
||||||
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner()));
|
given(this.owners.findByLastName("")).willReturn(Lists.newArrayList(george, new Owner()));
|
||||||
mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList"));
|
mockMvc.perform(get("/owners")).andExpect(status().isOk()).andExpect(view().name("owners/ownersList"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessFindFormByLastName() throws Exception {
|
void testProcessFindFormByLastName() throws Exception {
|
||||||
given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george));
|
given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george));
|
||||||
mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection())
|
mockMvc.perform(get("/owners").param("lastName", "Franklin")).andExpect(status().is3xxRedirection())
|
||||||
.andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID));
|
.andExpect(view().name("redirect:/owners/" + TEST_OWNER_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessFindFormNoOwnersFound() throws Exception {
|
void testProcessFindFormNoOwnersFound() throws Exception {
|
||||||
mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk())
|
mockMvc.perform(get("/owners").param("lastName", "Unknown Surname")).andExpect(status().isOk())
|
||||||
.andExpect(model().attributeHasFieldErrors("owner", "lastName"))
|
.andExpect(model().attributeHasFieldErrors("owner", "lastName"))
|
||||||
.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))
|
.andExpect(model().attributeHasFieldErrorCode("owner", "lastName", "notFound"))
|
||||||
.andExpect(view().name("owners/findOwners"));
|
.andExpect(view().name("owners/findOwners"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitUpdateOwnerForm() throws Exception {
|
void testInitUpdateOwnerForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk())
|
mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID)).andExpect(status().isOk())
|
||||||
.andExpect(model().attributeExists("owner"))
|
.andExpect(model().attributeExists("owner"))
|
||||||
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
|
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
|
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
||||||
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessUpdateOwnerFormSuccess() throws Exception {
|
void testProcessUpdateOwnerFormSuccess() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
|
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
|
||||||
.param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London")
|
.param("lastName", "Bloggs").param("address", "123 Caramel Street").param("city", "London")
|
||||||
.param("telephone", "01616291589")).andExpect(status().is3xxRedirection())
|
.param("telephone", "01616291589")).andExpect(status().is3xxRedirection())
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessUpdateOwnerFormHasErrors() throws Exception {
|
void testProcessUpdateOwnerFormHasErrors() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
|
mockMvc.perform(post("/owners/{ownerId}/edit", TEST_OWNER_ID).param("firstName", "Joe")
|
||||||
.param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk())
|
.param("lastName", "Bloggs").param("city", "London")).andExpect(status().isOk())
|
||||||
.andExpect(model().attributeHasErrors("owner"))
|
.andExpect(model().attributeHasErrors("owner"))
|
||||||
.andExpect(model().attributeHasFieldErrors("owner", "address"))
|
.andExpect(model().attributeHasFieldErrors("owner", "address"))
|
||||||
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
|
.andExpect(model().attributeHasFieldErrors("owner", "telephone"))
|
||||||
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testShowOwner() throws Exception {
|
void testShowOwner() throws Exception {
|
||||||
mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk())
|
mockMvc.perform(get("/owners/{ownerId}", TEST_OWNER_ID)).andExpect(status().isOk())
|
||||||
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
|
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
|
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("pets", not(empty()))))
|
.andExpect(model().attribute("owner", hasProperty("pets", not(empty()))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher<List<Pet>>() {
|
.andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher<List<Pet>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Object item) {
|
public boolean matches(Object item) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Pet> pets = (List<Pet>) item;
|
List<Pet> pets = (List<Pet>) item;
|
||||||
Pet pet = pets.get(0);
|
Pet pet = pets.get(0);
|
||||||
if (pet.getVisits().isEmpty()) {
|
if (pet.getVisits().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void describeTo(Description description) {
|
public void describeTo(Description description) {
|
||||||
description.appendText("Max did not have any visits");
|
description.appendText("Max did not have any visits");
|
||||||
}
|
}
|
||||||
}))).andExpect(view().name("owners/ownerDetails"));
|
}))).andExpect(view().name("owners/ownerDetails"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,75 +39,75 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||||
* @author Colin But
|
* @author Colin But
|
||||||
*/
|
*/
|
||||||
@WebMvcTest(value = PetController.class,
|
@WebMvcTest(value = PetController.class,
|
||||||
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
|
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
|
||||||
class PetControllerTests {
|
class PetControllerTests {
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
private static final int TEST_OWNER_ID = 1;
|
||||||
|
|
||||||
private static final int TEST_PET_ID = 1;
|
private static final int TEST_PET_ID = 1;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private PetRepository pets;
|
private PetRepository pets;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private OwnerRepository owners;
|
private OwnerRepository owners;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
PetType cat = new PetType();
|
PetType cat = new PetType();
|
||||||
cat.setId(3);
|
cat.setId(3);
|
||||||
cat.setName("hamster");
|
cat.setName("hamster");
|
||||||
given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat));
|
given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat));
|
||||||
given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner());
|
given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner());
|
||||||
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitCreationForm() throws Exception {
|
void testInitCreationForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk())
|
mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk())
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet"));
|
.andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessCreationFormSuccess() throws Exception {
|
void testProcessCreationFormSuccess() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty")
|
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty")
|
||||||
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessCreationFormHasErrors() throws Exception {
|
void testProcessCreationFormHasErrors() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate",
|
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate",
|
||||||
"2015-02-12")).andExpect(model().attributeHasNoErrors("owner"))
|
"2015-02-12")).andExpect(model().attributeHasNoErrors("owner"))
|
||||||
.andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type"))
|
.andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type"))
|
||||||
.andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk())
|
.andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk())
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitUpdateForm() throws Exception {
|
void testInitUpdateForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID))
|
mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID))
|
||||||
.andExpect(status().isOk()).andExpect(model().attributeExists("pet"))
|
.andExpect(status().isOk()).andExpect(model().attributeExists("pet"))
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessUpdateFormSuccess() throws Exception {
|
void testProcessUpdateFormSuccess() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
||||||
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessUpdateFormHasErrors() throws Exception {
|
void testProcessUpdateFormHasErrors() throws Exception {
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
||||||
.param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner"))
|
.param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner"))
|
||||||
.andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk())
|
.andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk())
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,56 +40,56 @@ import static org.mockito.BDDMockito.given;
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class PetTypeFormatterTests {
|
class PetTypeFormatterTests {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private PetRepository pets;
|
private PetRepository pets;
|
||||||
|
|
||||||
private PetTypeFormatter petTypeFormatter;
|
private PetTypeFormatter petTypeFormatter;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
this.petTypeFormatter = new PetTypeFormatter(pets);
|
this.petTypeFormatter = new PetTypeFormatter(pets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPrint() {
|
void testPrint() {
|
||||||
PetType petType = new PetType();
|
PetType petType = new PetType();
|
||||||
petType.setName("Hamster");
|
petType.setName("Hamster");
|
||||||
String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH);
|
String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH);
|
||||||
assertThat(petTypeName).isEqualTo("Hamster");
|
assertThat(petTypeName).isEqualTo("Hamster");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldParse() throws ParseException {
|
void shouldParse() throws ParseException {
|
||||||
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
||||||
PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH);
|
PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH);
|
||||||
assertThat(petType.getName()).isEqualTo("Bird");
|
assertThat(petType.getName()).isEqualTo("Bird");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldThrowParseException() throws ParseException {
|
void shouldThrowParseException() throws ParseException {
|
||||||
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
||||||
Assertions.assertThrows(ParseException.class, () -> {
|
Assertions.assertThrows(ParseException.class, () -> {
|
||||||
petTypeFormatter.parse("Fish", Locale.ENGLISH);
|
petTypeFormatter.parse("Fish", Locale.ENGLISH);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to produce some sample pet types just for test purpose
|
* Helper method to produce some sample pet types just for test purpose
|
||||||
* @return {@link Collection} of {@link PetType}
|
* @return {@link Collection} of {@link PetType}
|
||||||
*/
|
*/
|
||||||
private List<PetType> makePetTypes() {
|
private List<PetType> makePetTypes() {
|
||||||
List<PetType> petTypes = new ArrayList<>();
|
List<PetType> petTypes = new ArrayList<>();
|
||||||
petTypes.add(new PetType() {
|
petTypes.add(new PetType() {
|
||||||
{
|
{
|
||||||
setName("Dog");
|
setName("Dog");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
petTypes.add(new PetType() {
|
petTypes.add(new PetType() {
|
||||||
{
|
{
|
||||||
setName("Bird");
|
setName("Bird");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return petTypes;
|
return petTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,40 +39,40 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||||
@WebMvcTest(VisitController.class)
|
@WebMvcTest(VisitController.class)
|
||||||
class VisitControllerTests {
|
class VisitControllerTests {
|
||||||
|
|
||||||
private static final int TEST_PET_ID = 1;
|
private static final int TEST_PET_ID = 1;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private VisitRepository visits;
|
private VisitRepository visits;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private PetRepository pets;
|
private PetRepository pets;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void init() {
|
void init() {
|
||||||
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testInitNewVisitForm() throws Exception {
|
void testInitNewVisitForm() throws Exception {
|
||||||
mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk())
|
mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk())
|
||||||
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessNewVisitFormSuccess() throws Exception {
|
void testProcessNewVisitFormSuccess() throws Exception {
|
||||||
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")
|
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")
|
||||||
.param("description", "Visit Description")).andExpect(status().is3xxRedirection())
|
.param("description", "Visit Description")).andExpect(status().is3xxRedirection())
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testProcessNewVisitFormHasErrors() throws Exception {
|
void testProcessNewVisitFormHasErrors() throws Exception {
|
||||||
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George"))
|
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George"))
|
||||||
.andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk())
|
.andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk())
|
||||||
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,159 +69,159 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class))
|
@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class))
|
||||||
class ClinicServiceTests {
|
class ClinicServiceTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected OwnerRepository owners;
|
protected OwnerRepository owners;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected PetRepository pets;
|
protected PetRepository pets;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected VisitRepository visits;
|
protected VisitRepository visits;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected VetRepository vets;
|
protected VetRepository vets;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindOwnersByLastName() {
|
void shouldFindOwnersByLastName() {
|
||||||
Collection<Owner> owners = this.owners.findByLastName("Davis");
|
Collection<Owner> owners = this.owners.findByLastName("Davis");
|
||||||
assertThat(owners).hasSize(2);
|
assertThat(owners).hasSize(2);
|
||||||
|
|
||||||
owners = this.owners.findByLastName("Daviss");
|
owners = this.owners.findByLastName("Daviss");
|
||||||
assertThat(owners).isEmpty();
|
assertThat(owners).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindSingleOwnerWithPet() {
|
void shouldFindSingleOwnerWithPet() {
|
||||||
Owner owner = this.owners.findById(1);
|
Owner owner = this.owners.findById(1);
|
||||||
assertThat(owner.getLastName()).startsWith("Franklin");
|
assertThat(owner.getLastName()).startsWith("Franklin");
|
||||||
assertThat(owner.getPets()).hasSize(1);
|
assertThat(owner.getPets()).hasSize(1);
|
||||||
assertThat(owner.getPets().get(0).getType()).isNotNull();
|
assertThat(owner.getPets().get(0).getType()).isNotNull();
|
||||||
assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat");
|
assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
void shouldInsertOwner() {
|
void shouldInsertOwner() {
|
||||||
Collection<Owner> owners = this.owners.findByLastName("Schultz");
|
Collection<Owner> owners = this.owners.findByLastName("Schultz");
|
||||||
int found = owners.size();
|
int found = owners.size();
|
||||||
|
|
||||||
Owner owner = new Owner();
|
Owner owner = new Owner();
|
||||||
owner.setFirstName("Sam");
|
owner.setFirstName("Sam");
|
||||||
owner.setLastName("Schultz");
|
owner.setLastName("Schultz");
|
||||||
owner.setAddress("4, Evans Street");
|
owner.setAddress("4, Evans Street");
|
||||||
owner.setCity("Wollongong");
|
owner.setCity("Wollongong");
|
||||||
owner.setTelephone("4444444444");
|
owner.setTelephone("4444444444");
|
||||||
this.owners.save(owner);
|
this.owners.save(owner);
|
||||||
assertThat(owner.getId().longValue()).isNotEqualTo(0);
|
assertThat(owner.getId().longValue()).isNotEqualTo(0);
|
||||||
|
|
||||||
owners = this.owners.findByLastName("Schultz");
|
owners = this.owners.findByLastName("Schultz");
|
||||||
assertThat(owners.size()).isEqualTo(found + 1);
|
assertThat(owners.size()).isEqualTo(found + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
void shouldUpdateOwner() {
|
void shouldUpdateOwner() {
|
||||||
Owner owner = this.owners.findById(1);
|
Owner owner = this.owners.findById(1);
|
||||||
String oldLastName = owner.getLastName();
|
String oldLastName = owner.getLastName();
|
||||||
String newLastName = oldLastName + "X";
|
String newLastName = oldLastName + "X";
|
||||||
|
|
||||||
owner.setLastName(newLastName);
|
owner.setLastName(newLastName);
|
||||||
this.owners.save(owner);
|
this.owners.save(owner);
|
||||||
|
|
||||||
// retrieving new name from database
|
// retrieving new name from database
|
||||||
owner = this.owners.findById(1);
|
owner = this.owners.findById(1);
|
||||||
assertThat(owner.getLastName()).isEqualTo(newLastName);
|
assertThat(owner.getLastName()).isEqualTo(newLastName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindPetWithCorrectId() {
|
void shouldFindPetWithCorrectId() {
|
||||||
Pet pet7 = this.pets.findById(7);
|
Pet pet7 = this.pets.findById(7);
|
||||||
assertThat(pet7.getName()).startsWith("Samantha");
|
assertThat(pet7.getName()).startsWith("Samantha");
|
||||||
assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean");
|
assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindAllPetTypes() {
|
void shouldFindAllPetTypes() {
|
||||||
Collection<PetType> petTypes = this.pets.findPetTypes();
|
Collection<PetType> petTypes = this.pets.findPetTypes();
|
||||||
|
|
||||||
PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1);
|
PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1);
|
||||||
assertThat(petType1.getName()).isEqualTo("cat");
|
assertThat(petType1.getName()).isEqualTo("cat");
|
||||||
PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4);
|
PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4);
|
||||||
assertThat(petType4.getName()).isEqualTo("snake");
|
assertThat(petType4.getName()).isEqualTo("snake");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
void shouldInsertPetIntoDatabaseAndGenerateId() {
|
void shouldInsertPetIntoDatabaseAndGenerateId() {
|
||||||
Owner owner6 = this.owners.findById(6);
|
Owner owner6 = this.owners.findById(6);
|
||||||
int found = owner6.getPets().size();
|
int found = owner6.getPets().size();
|
||||||
|
|
||||||
Pet pet = new Pet();
|
Pet pet = new Pet();
|
||||||
pet.setName("bowser");
|
pet.setName("bowser");
|
||||||
Collection<PetType> types = this.pets.findPetTypes();
|
Collection<PetType> types = this.pets.findPetTypes();
|
||||||
pet.setType(EntityUtils.getById(types, PetType.class, 2));
|
pet.setType(EntityUtils.getById(types, PetType.class, 2));
|
||||||
pet.setBirthDate(LocalDate.now());
|
pet.setBirthDate(LocalDate.now());
|
||||||
owner6.addPet(pet);
|
owner6.addPet(pet);
|
||||||
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
||||||
|
|
||||||
this.pets.save(pet);
|
this.pets.save(pet);
|
||||||
this.owners.save(owner6);
|
this.owners.save(owner6);
|
||||||
|
|
||||||
owner6 = this.owners.findById(6);
|
owner6 = this.owners.findById(6);
|
||||||
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
||||||
// checks that id has been generated
|
// checks that id has been generated
|
||||||
assertThat(pet.getId()).isNotNull();
|
assertThat(pet.getId()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
void shouldUpdatePetName() throws Exception {
|
void shouldUpdatePetName() throws Exception {
|
||||||
Pet pet7 = this.pets.findById(7);
|
Pet pet7 = this.pets.findById(7);
|
||||||
String oldName = pet7.getName();
|
String oldName = pet7.getName();
|
||||||
|
|
||||||
String newName = oldName + "X";
|
String newName = oldName + "X";
|
||||||
pet7.setName(newName);
|
pet7.setName(newName);
|
||||||
this.pets.save(pet7);
|
this.pets.save(pet7);
|
||||||
|
|
||||||
pet7 = this.pets.findById(7);
|
pet7 = this.pets.findById(7);
|
||||||
assertThat(pet7.getName()).isEqualTo(newName);
|
assertThat(pet7.getName()).isEqualTo(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindVets() {
|
void shouldFindVets() {
|
||||||
Collection<Vet> vets = this.vets.findAll();
|
Collection<Vet> vets = this.vets.findAll();
|
||||||
|
|
||||||
Vet vet = EntityUtils.getById(vets, Vet.class, 3);
|
Vet vet = EntityUtils.getById(vets, Vet.class, 3);
|
||||||
assertThat(vet.getLastName()).isEqualTo("Douglas");
|
assertThat(vet.getLastName()).isEqualTo("Douglas");
|
||||||
assertThat(vet.getNrOfSpecialties()).isEqualTo(2);
|
assertThat(vet.getNrOfSpecialties()).isEqualTo(2);
|
||||||
assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry");
|
assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry");
|
||||||
assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery");
|
assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Transactional
|
@Transactional
|
||||||
void shouldAddNewVisitForPet() {
|
void shouldAddNewVisitForPet() {
|
||||||
Pet pet7 = this.pets.findById(7);
|
Pet pet7 = this.pets.findById(7);
|
||||||
int found = pet7.getVisits().size();
|
int found = pet7.getVisits().size();
|
||||||
Visit visit = new Visit();
|
Visit visit = new Visit();
|
||||||
pet7.addVisit(visit);
|
pet7.addVisit(visit);
|
||||||
visit.setDescription("test");
|
visit.setDescription("test");
|
||||||
this.visits.save(visit);
|
this.visits.save(visit);
|
||||||
this.pets.save(pet7);
|
this.pets.save(pet7);
|
||||||
|
|
||||||
pet7 = this.pets.findById(7);
|
pet7 = this.pets.findById(7);
|
||||||
assertThat(pet7.getVisits().size()).isEqualTo(found + 1);
|
assertThat(pet7.getVisits().size()).isEqualTo(found + 1);
|
||||||
assertThat(visit.getId()).isNotNull();
|
assertThat(visit.getId()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldFindVisitsByPetId() throws Exception {
|
void shouldFindVisitsByPetId() throws Exception {
|
||||||
Collection<Visit> visits = this.visits.findByPetId(7);
|
Collection<Visit> visits = this.visits.findByPetId(7);
|
||||||
assertThat(visits).hasSize(2);
|
assertThat(visits).hasSize(2);
|
||||||
Visit[] visitArr = visits.toArray(new Visit[visits.size()]);
|
Visit[] visitArr = visits.toArray(new Visit[visits.size()]);
|
||||||
assertThat(visitArr[0].getDate()).isNotNull();
|
assertThat(visitArr[0].getDate()).isNotNull();
|
||||||
assertThat(visitArr[0].getPetId()).isEqualTo(7);
|
assertThat(visitArr[0].getPetId()).isEqualTo(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,22 +32,22 @@ import org.springframework.samples.petclinic.model.BaseEntity;
|
||||||
*/
|
*/
|
||||||
public abstract class EntityUtils {
|
public abstract class EntityUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up the entity of the given class with the given id in the given collection.
|
* Look up the entity of the given class with the given id in the given collection.
|
||||||
* @param entities the collection to search
|
* @param entities the collection to search
|
||||||
* @param entityClass the entity class to look up
|
* @param entityClass the entity class to look up
|
||||||
* @param entityId the entity id to look up
|
* @param entityId the entity id to look up
|
||||||
* @return the found entity
|
* @return the found entity
|
||||||
* @throws ObjectRetrievalFailureException if the entity was not found
|
* @throws ObjectRetrievalFailureException if the entity was not found
|
||||||
*/
|
*/
|
||||||
public static <T extends BaseEntity> T getById(Collection<T> entities, Class<T> entityClass, int entityId)
|
public static <T extends BaseEntity> T getById(Collection<T> entities, Class<T> entityClass, int entityId)
|
||||||
throws ObjectRetrievalFailureException {
|
throws ObjectRetrievalFailureException {
|
||||||
for (T entity : entities) {
|
for (T entity : entities) {
|
||||||
if (entity.getId() == entityId && entityClass.isInstance(entity)) {
|
if (entity.getId() == entityId && entityClass.isInstance(entity)) {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ObjectRetrievalFailureException(entityClass, entityId);
|
throw new ObjectRetrievalFailureException(entityClass, entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@WebMvcTest(controllers = CrashController.class)
|
@WebMvcTest(controllers = CrashController.class)
|
||||||
class CrashControllerTests {
|
class CrashControllerTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testTriggerException() throws Exception {
|
void testTriggerException() throws Exception {
|
||||||
mockMvc.perform(get("/oups")).andExpect(view().name("exception"))
|
mockMvc.perform(get("/oups")).andExpect(view().name("exception"))
|
||||||
.andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception"))
|
.andExpect(model().attributeExists("exception")).andExpect(forwardedUrl("exception"))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,41 +40,41 @@ import org.springframework.test.web.servlet.ResultActions;
|
||||||
@WebMvcTest(VetController.class)
|
@WebMvcTest(VetController.class)
|
||||||
class VetControllerTests {
|
class VetControllerTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private VetRepository vets;
|
private VetRepository vets;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
Vet james = new Vet();
|
Vet james = new Vet();
|
||||||
james.setFirstName("James");
|
james.setFirstName("James");
|
||||||
james.setLastName("Carter");
|
james.setLastName("Carter");
|
||||||
james.setId(1);
|
james.setId(1);
|
||||||
Vet helen = new Vet();
|
Vet helen = new Vet();
|
||||||
helen.setFirstName("Helen");
|
helen.setFirstName("Helen");
|
||||||
helen.setLastName("Leary");
|
helen.setLastName("Leary");
|
||||||
helen.setId(2);
|
helen.setId(2);
|
||||||
Specialty radiology = new Specialty();
|
Specialty radiology = new Specialty();
|
||||||
radiology.setId(1);
|
radiology.setId(1);
|
||||||
radiology.setName("radiology");
|
radiology.setName("radiology");
|
||||||
helen.addSpecialty(radiology);
|
helen.addSpecialty(radiology);
|
||||||
given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen));
|
given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testShowVetListHtml() throws Exception {
|
void testShowVetListHtml() throws Exception {
|
||||||
mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets"))
|
mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets"))
|
||||||
.andExpect(view().name("vets/vetList"));
|
.andExpect(view().name("vets/vetList"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testShowResourcesVetList() throws Exception {
|
void testShowResourcesVetList() throws Exception {
|
||||||
ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON))
|
ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
actions.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
actions.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(jsonPath("$.vetList[0].id").value(1));
|
.andExpect(jsonPath("$.vetList[0].id").value(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
class VetTests {
|
class VetTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSerialization() {
|
void testSerialization() {
|
||||||
Vet vet = new Vet();
|
Vet vet = new Vet();
|
||||||
vet.setFirstName("Zaphod");
|
vet.setFirstName("Zaphod");
|
||||||
vet.setLastName("Beeblebrox");
|
vet.setLastName("Beeblebrox");
|
||||||
vet.setId(123);
|
vet.setId(123);
|
||||||
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
|
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
|
||||||
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
|
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
|
||||||
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
|
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
|
||||||
assertThat(other.getId()).isEqualTo(vet.getId());
|
assertThat(other.getId()).isEqualTo(vet.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue