7 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic;
18 |
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.SpringBootApplication;
21 | import org.springframework.context.annotation.ImportRuntimeHints;
22 |
23 | /**
24 | * PetClinic Spring Boot Application.
25 | *
26 | * @author Dave Syer
27 | *
28 | */
29 | @SpringBootApplication
30 | @ImportRuntimeHints(PetClinicRuntimeHints.class)
31 | public class PetClinicApplication {
32 |
33 | public static void main(String[] args) {
34 | SpringApplication.run(PetClinicApplication.class, args);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/resources/templates/pets/createOrUpdatePetForm.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | New
8 | Pet
9 |
10 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/system/CrashController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.system;
17 |
18 | import org.springframework.stereotype.Controller;
19 | import org.springframework.web.bind.annotation.GetMapping;
20 |
21 | /**
22 | * Controller used to showcase what happens when an exception is thrown
23 | *
24 | * @author Michael Isvy
25 | *
26 | * Also see how a view that resolves to "error" has been added ("error.html").
27 | */
28 | @Controller
29 | class CrashController {
30 |
31 | @GetMapping("/oups")
32 | public String triggerException() {
33 | throw new RuntimeException(
34 | "Expected: controller used to showcase what " + "happens when an exception is thrown");
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/vet/Vets.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.vet;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | import jakarta.xml.bind.annotation.XmlElement;
22 | import jakarta.xml.bind.annotation.XmlRootElement;
23 |
24 | /**
25 | * Simple domain object representing a list of veterinarians. Mostly here to be used for
26 | * the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}.
27 | *
28 | * @author Arjen Poutsma
29 | */
30 | @XmlRootElement
31 | public class Vets {
32 |
33 | private List vets;
34 |
35 | @XmlElement
36 | public List getVetList() {
37 | if (vets == null) {
38 | vets = new ArrayList<>();
39 | }
40 | return vets;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.model;
17 |
18 | import jakarta.persistence.Column;
19 | import jakarta.persistence.MappedSuperclass;
20 |
21 | /**
22 | * Simple JavaBean domain object adds a name property to BaseEntity. Used as
23 | * a base class for objects needing these properties.
24 | *
25 | * @author Ken Krebs
26 | * @author Juergen Hoeller
27 | */
28 | @MappedSuperclass
29 | public class NamedEntity extends BaseEntity {
30 |
31 | @Column(name = "name")
32 | private String name;
33 |
34 | public String getName() {
35 | return this.name;
36 | }
37 |
38 | public void setName(String name) {
39 | this.name = name;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return this.getName();
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/samples/petclinic/vet/VetTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.vet;
17 |
18 | import org.junit.jupiter.api.Test;
19 | import org.springframework.util.SerializationUtils;
20 |
21 | import static org.assertj.core.api.Assertions.assertThat;
22 |
23 | /**
24 | * @author Dave Syer
25 | */
26 | class VetTests {
27 |
28 | @Test
29 | void testSerialization() {
30 | Vet vet = new Vet();
31 | vet.setFirstName("Zaphod");
32 | vet.setLastName("Beeblebrox");
33 | vet.setId(123);
34 | @SuppressWarnings("deprecation")
35 | Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
36 | assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
37 | assertThat(other.getLastName()).isEqualTo(vet.getLastName());
38 | assertThat(other.getId()).isEqualTo(vet.getId());
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.model;
17 |
18 | import java.io.Serializable;
19 |
20 | import jakarta.persistence.GeneratedValue;
21 | import jakarta.persistence.GenerationType;
22 | import jakarta.persistence.Id;
23 | import jakarta.persistence.MappedSuperclass;
24 |
25 | /**
26 | * Simple JavaBean domain object with an id property. Used as a base class for objects
27 | * needing this property.
28 | *
29 | * @author Ken Krebs
30 | * @author Juergen Hoeller
31 | */
32 | @MappedSuperclass
33 | public class BaseEntity implements Serializable {
34 |
35 | @Id
36 | @GeneratedValue(strategy = GenerationType.IDENTITY)
37 | private Integer id;
38 |
39 | public Integer getId() {
40 | return id;
41 | }
42 |
43 | public void setId(Integer id) {
44 | this.id = id;
45 | }
46 |
47 | public boolean isNew() {
48 | return this.id == null;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/resources/db/postgres/schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS vets (
2 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3 | first_name TEXT,
4 | last_name TEXT
5 | );
6 | CREATE INDEX ON vets (last_name);
7 |
8 | CREATE TABLE IF NOT EXISTS specialties (
9 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
10 | name TEXT
11 | );
12 | CREATE INDEX ON specialties (name);
13 |
14 | CREATE TABLE IF NOT EXISTS vet_specialties (
15 | vet_id INT NOT NULL REFERENCES vets (id),
16 | specialty_id INT NOT NULL REFERENCES specialties (id),
17 | UNIQUE (vet_id, specialty_id)
18 | );
19 |
20 | CREATE TABLE IF NOT EXISTS types (
21 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
22 | name TEXT
23 | );
24 | CREATE INDEX ON types (name);
25 |
26 | CREATE TABLE IF NOT EXISTS owners (
27 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
28 | first_name TEXT,
29 | last_name TEXT,
30 | address TEXT,
31 | city TEXT,
32 | telephone TEXT
33 | );
34 | CREATE INDEX ON owners (last_name);
35 |
36 | CREATE TABLE IF NOT EXISTS pets (
37 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
38 | name TEXT,
39 | birth_date DATE,
40 | type_id INT NOT NULL REFERENCES types (id),
41 | owner_id INT REFERENCES owners (id)
42 | );
43 | CREATE INDEX ON pets (name);
44 | CREATE INDEX ON pets (owner_id);
45 |
46 | CREATE TABLE IF NOT EXISTS visits (
47 | id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
48 | pet_id INT REFERENCES pets (id),
49 | visit_date DATE,
50 | description TEXT
51 | );
52 | CREATE INDEX ON visits (pet_id);
53 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/model/Person.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.model;
17 |
18 | import jakarta.persistence.Column;
19 | import jakarta.persistence.MappedSuperclass;
20 | import jakarta.validation.constraints.NotBlank;
21 |
22 | /**
23 | * Simple JavaBean domain object representing an person.
24 | *
25 | * @author Ken Krebs
26 | */
27 | @MappedSuperclass
28 | public class Person extends BaseEntity {
29 |
30 | @Column(name = "first_name")
31 | @NotBlank
32 | private String firstName;
33 |
34 | @Column(name = "last_name")
35 | @NotBlank
36 | private String lastName;
37 |
38 | public String getFirstName() {
39 | return this.firstName;
40 | }
41 |
42 | public void setFirstName(String firstName) {
43 | this.firstName = firstName;
44 | }
45 |
46 | public String getLastName() {
47 | return this.lastName;
48 | }
49 |
50 | public void setLastName(String lastName) {
51 | this.lastName = lastName;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic;
18 |
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
21 | import org.springframework.context.annotation.Bean;
22 | import org.springframework.context.annotation.Configuration;
23 | import org.springframework.context.annotation.Profile;
24 | import org.testcontainers.containers.MySQLContainer;
25 |
26 | /**
27 | * PetClinic Spring Boot Application.
28 | *
29 | * @author Dave Syer
30 | *
31 | */
32 | @Configuration
33 | public class MysqlTestApplication {
34 |
35 | @ServiceConnection
36 | @Profile("mysql")
37 | @Bean
38 | static MySQLContainer> container() {
39 | return new MySQLContainer<>("mysql:8.2");
40 | }
41 |
42 | public static void main(String[] args) {
43 | SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql");
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/samples/petclinic/system/CrashControllerTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic.system;
18 |
19 | import static org.junit.jupiter.api.Assertions.assertEquals;
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | import org.junit.jupiter.api.Test;
23 |
24 | /**
25 | * Test class for {@link CrashController}
26 | *
27 | * @author Colin But
28 | * @author Alex Lutz
29 | */
30 | // Waiting https://github.com/spring-projects/spring-boot/issues/5574 ..good
31 | // luck ((plain(st) UNIT test)! :)
32 | class CrashControllerTests {
33 |
34 | CrashController testee = new CrashController();
35 |
36 | @Test
37 | void testTriggerException() throws Exception {
38 | RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
39 | testee.triggerException();
40 | });
41 |
42 | assertEquals("Expected: controller used to showcase what happens when an exception is thrown",
43 | thrown.getMessage());
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/scss/header.scss:
--------------------------------------------------------------------------------
1 | .navbar {
2 | border-top: 4px solid #6db33f;
3 | background-color: #34302d;
4 | margin-bottom: 0px;
5 | border-bottom: 0;
6 | border-left: 0;
7 | border-right: 0;
8 | }
9 |
10 | .navbar a.navbar-brand {
11 | background: url("../images/spring-logo-dataflow.png") -1px -1px no-repeat;
12 | margin: 12px 0 6px;
13 | width: 229px;
14 | height: 46px;
15 | display: inline-block;
16 | text-decoration: none;
17 | padding: 0;
18 | }
19 |
20 | .navbar a.navbar-brand span {
21 | display: block;
22 | width: 229px;
23 | height: 46px;
24 | background: url("../images/spring-logo-dataflow.png") -1px -48px no-repeat;
25 | opacity: 0;
26 | -moz-transition: opacity 0.12s ease-in-out;
27 | -webkit-transition: opacity 0.12s ease-in-out;
28 | -o-transition: opacity 0.12s ease-in-out;
29 | }
30 |
31 | .navbar a:hover.navbar-brand span {
32 | opacity: 1;
33 | }
34 |
35 | .navbar li > a, .navbar-text {
36 | font-family: "montserratregular", sans-serif;
37 | text-shadow: none;
38 | font-size: 14px;
39 |
40 | /* line-height: 14px; */
41 | padding: 28px 20px;
42 | transition: all 0.15s;
43 | -webkit-transition: all 0.15s;
44 | -moz-transition: all 0.15s;
45 | -o-transition: all 0.15s;
46 | -ms-transition: all 0.15s;
47 | }
48 |
49 | .navbar li > a {
50 | text-transform: uppercase;
51 | }
52 |
53 | .navbar .navbar-text {
54 | margin-top: 0;
55 | margin-bottom: 0;
56 | }
57 | .navbar li:hover > a {
58 | color: #eeeeee;
59 | background-color: #6db33f;
60 | }
61 |
62 | .navbar-toggle {
63 | border-width: 0;
64 |
65 | .icon-bar + .icon-bar {
66 | margin-top: 3px;
67 | }
68 | .icon-bar {
69 | width: 19px;
70 | height: 3px;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/scss/typography.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'varela_roundregular';
3 |
4 | src: url('../fonts/varela_round-webfont.eot');
5 | src: url('../fonts/varela_round-webfont.eot?#iefix') format('embedded-opentype'),
6 | url('../fonts/varela_round-webfont.woff') format('woff'),
7 | url('../fonts/varela_round-webfont.ttf') format('truetype'),
8 | url('../fonts/varela_round-webfont.svg#varela_roundregular') format('svg');
9 | font-weight: normal;
10 | font-style: normal;
11 | }
12 |
13 | @font-face {
14 | font-family: 'montserratregular';
15 | src: url('../fonts/montserrat-webfont.eot');
16 | src: url('../fonts/montserrat-webfont.eot?#iefix') format('embedded-opentype'),
17 | url('../fonts/montserrat-webfont.woff') format('woff'),
18 | url('../fonts/montserrat-webfont.ttf') format('truetype'),
19 | url('../fonts/montserrat-webfont.svg#montserratregular') format('svg');
20 | font-weight: normal;
21 | font-style: normal;
22 | }
23 |
24 | body, h1, h2, h3, p, input {
25 | margin: 0;
26 | font-weight: 400;
27 | font-family: "varela_roundregular", sans-serif;
28 | color: #34302d;
29 | }
30 |
31 | h1 {
32 | font-size: 24px;
33 | line-height: 30px;
34 | font-family: "montserratregular", sans-serif;
35 | }
36 |
37 | h2 {
38 | font-size: 18px;
39 | font-weight: 700;
40 | line-height: 24px;
41 | margin-bottom: 10px;
42 | font-family: "montserratregular", sans-serif;
43 | }
44 |
45 | h3 {
46 | font-size: 16px;
47 | line-height: 24px;
48 | margin-bottom: 10px;
49 | font-weight: 700;
50 | }
51 |
52 | p {
53 | //font-size: 15px;
54 | //line-height: 24px;
55 | }
56 |
57 | strong {
58 | font-weight: 700;
59 | font-family: "montserratregular", sans-serif;
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic;
18 |
19 | import org.springframework.aot.hint.RuntimeHints;
20 | import org.springframework.aot.hint.RuntimeHintsRegistrar;
21 | import org.springframework.samples.petclinic.model.BaseEntity;
22 | import org.springframework.samples.petclinic.model.Person;
23 | import org.springframework.samples.petclinic.vet.Vet;
24 |
25 | public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
26 |
27 | @Override
28 | public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
29 | hints.resources().registerPattern("db/*"); // https://github.com/spring-projects/spring-boot/issues/32654
30 | hints.resources().registerPattern("messages/*");
31 | hints.resources().registerPattern("META-INF/resources/webjars/*");
32 | hints.resources().registerPattern("mysql-default-conf");
33 | hints.serialization().registerType(BaseEntity.class);
34 | hints.serialization().registerType(Person.class);
35 | hints.serialization().registerType(Vet.class);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/resources/db/mysql/schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS vets (
2 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
3 | first_name VARCHAR(30),
4 | last_name VARCHAR(30),
5 | INDEX(last_name)
6 | ) engine=InnoDB;
7 |
8 | CREATE TABLE IF NOT EXISTS specialties (
9 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
10 | name VARCHAR(80),
11 | INDEX(name)
12 | ) engine=InnoDB;
13 |
14 | CREATE TABLE IF NOT EXISTS vet_specialties (
15 | vet_id INT(4) UNSIGNED NOT NULL,
16 | specialty_id INT(4) UNSIGNED NOT NULL,
17 | FOREIGN KEY (vet_id) REFERENCES vets(id),
18 | FOREIGN KEY (specialty_id) REFERENCES specialties(id),
19 | UNIQUE (vet_id,specialty_id)
20 | ) engine=InnoDB;
21 |
22 | CREATE TABLE IF NOT EXISTS types (
23 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
24 | name VARCHAR(80),
25 | INDEX(name)
26 | ) engine=InnoDB;
27 |
28 | CREATE TABLE IF NOT EXISTS owners (
29 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
30 | first_name VARCHAR(30),
31 | last_name VARCHAR(30),
32 | address VARCHAR(255),
33 | city VARCHAR(80),
34 | telephone VARCHAR(20),
35 | INDEX(last_name)
36 | ) engine=InnoDB;
37 |
38 | CREATE TABLE IF NOT EXISTS pets (
39 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
40 | name VARCHAR(30),
41 | birth_date DATE,
42 | type_id INT(4) UNSIGNED NOT NULL,
43 | owner_id INT(4) UNSIGNED,
44 | INDEX(name),
45 | FOREIGN KEY (owner_id) REFERENCES owners(id),
46 | FOREIGN KEY (type_id) REFERENCES types(id)
47 | ) engine=InnoDB;
48 |
49 | CREATE TABLE IF NOT EXISTS visits (
50 | id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
51 | pet_id INT(4) UNSIGNED,
52 | visit_date DATE,
53 | description VARCHAR(255),
54 | FOREIGN KEY (pet_id) REFERENCES pets(id)
55 | ) engine=InnoDB;
56 |
--------------------------------------------------------------------------------
/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt:
--------------------------------------------------------------------------------
1 | ================================================================================
2 | === Spring PetClinic sample application - MySQL Configuration ===
3 | ================================================================================
4 |
5 | @author Sam Brannen
6 | @author Costin Leau
7 | @author Dave Syer
8 |
9 | --------------------------------------------------------------------------------
10 |
11 | 1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x),
12 | which can be found here: https://dev.mysql.com/downloads/. Or run the
13 | "docker-compose.yml" from the root of the project (if you have docker installed
14 | locally):
15 |
16 | $ docker-compose up
17 | ...
18 | mysql_1_eedb4818d817 | MySQL init process done. Ready for start up.
19 | ...
20 |
21 | 2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql"
22 | scripts. You can connect to the database running in the docker container using
23 | `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there
24 | because the petclinic user is already set up if you use the provided `docker-compose.yml`.
25 |
26 | 3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command
27 | line, but any way that sets that property in a Spring Boot app should work). For example use
28 |
29 | mvn spring-boot:run -Dspring-boot.run.profiles=mysql
30 |
31 | To activate the profile on the command line.
32 |
33 | N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value
34 | as it is configured by default. This condition is taken care of automatically by the
35 | docker-compose configuration provided, or by the `user.sql` script if you run that as
36 | root.
37 |
--------------------------------------------------------------------------------
/src/main/resources/templates/pets/createOrUpdateVisitForm.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 | New
8 | Visit
9 |
10 |
11 | Pet
12 |
13 |
14 |
15 |
Name
16 |
Birth Date
17 |
Type
18 |
Owner
19 |
20 |
21 |
22 |
23 |
25 |
26 |
28 |
29 |
30 |
31 |
46 |
47 |
48 | Previous Visits
49 |
50 |
51 |
Date
52 |
Description
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/owner/Visit.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.owner;
17 |
18 | import java.time.LocalDate;
19 |
20 | import org.springframework.format.annotation.DateTimeFormat;
21 | import org.springframework.samples.petclinic.model.BaseEntity;
22 |
23 | import jakarta.persistence.Column;
24 | import jakarta.persistence.Entity;
25 | import jakarta.persistence.Table;
26 | import jakarta.validation.constraints.NotBlank;
27 |
28 | /**
29 | * Simple JavaBean domain object representing a visit.
30 | *
31 | * @author Ken Krebs
32 | * @author Dave Syer
33 | */
34 | @Entity
35 | @Table(name = "visits")
36 | public class Visit extends BaseEntity {
37 |
38 | @Column(name = "visit_date")
39 | @DateTimeFormat(pattern = "yyyy-MM-dd")
40 | private LocalDate date;
41 |
42 | @NotBlank
43 | private String description;
44 |
45 | /**
46 | * Creates a new instance of Visit for the current date
47 | */
48 | public Visit() {
49 | this.date = LocalDate.now();
50 | }
51 |
52 | public LocalDate getDate() {
53 | return this.date;
54 | }
55 |
56 | public void setDate(LocalDate date) {
57 | this.date = date;
58 | }
59 |
60 | public String getDescription() {
61 | return this.description;
62 | }
63 |
64 | public void setDescription(String description) {
65 | this.description = description;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/owner/PetValidator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.samples.petclinic.owner;
17 |
18 | import org.springframework.util.StringUtils;
19 | import org.springframework.validation.Errors;
20 | import org.springframework.validation.Validator;
21 |
22 | /**
23 | * Validator for Pet forms.
24 | *
25 | * We're not using Bean Validation annotations here because it is easier to define such
26 | * validation rule in Java.
27 | *
28 | *
29 | * @author Ken Krebs
30 | * @author Juergen Hoeller
31 | */
32 | public class PetValidator implements Validator {
33 |
34 | private static final String REQUIRED = "required";
35 |
36 | @Override
37 | public void validate(Object obj, Errors errors) {
38 | Pet pet = (Pet) obj;
39 | String name = pet.getName();
40 | // name validation
41 | if (!StringUtils.hasText(name)) {
42 | errors.rejectValue("name", REQUIRED, REQUIRED);
43 | }
44 |
45 | // type validation
46 | if (pet.isNew() && pet.getType() == null) {
47 | errors.rejectValue("type", REQUIRED, REQUIRED);
48 | }
49 |
50 | // birth date validation
51 | if (pet.getBirthDate() == null) {
52 | errors.rejectValue("birthDate", REQUIRED, REQUIRED);
53 | }
54 | }
55 |
56 | /**
57 | * This Validator validates *just* Pet instances
58 | */
59 | @Override
60 | public boolean supports(Class> clazz) {
61 | return Pet.class.isAssignableFrom(clazz);
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/test/java/org/springframework/samples/petclinic/service/EntityUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic.service;
18 |
19 | import org.springframework.orm.ObjectRetrievalFailureException;
20 | import org.springframework.samples.petclinic.model.BaseEntity;
21 |
22 | import java.util.Collection;
23 |
24 | /**
25 | * Utility methods for handling entities. Separate from the BaseEntity class mainly
26 | * because of dependency on the ORM-associated ObjectRetrievalFailureException.
27 | *
28 | * @author Juergen Hoeller
29 | * @author Sam Brannen
30 | * @see org.springframework.samples.petclinic.model.BaseEntity
31 | * @since 29.10.2003
32 | */
33 | public abstract class EntityUtils {
34 |
35 | /**
36 | * Look up the entity of the given class with the given id in the given collection.
37 | * @param entities the collection to search
38 | * @param entityClass the entity class to look up
39 | * @param entityId the entity id to look up
40 | * @return the found entity
41 | * @throws ObjectRetrievalFailureException if the entity was not found
42 | */
43 | public static T getById(Collection entities, Class entityClass, int entityId)
44 | throws ObjectRetrievalFailureException {
45 | for (T entity : entities) {
46 | if (entity.getId() == entityId && entityClass.isInstance(entity)) {
47 | return entity;
48 | }
49 | }
50 | throw new ObjectRetrievalFailureException(entityClass, entityId);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/resources/db/hsqldb/schema.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE vet_specialties IF EXISTS;
2 | DROP TABLE vets IF EXISTS;
3 | DROP TABLE specialties IF EXISTS;
4 | DROP TABLE visits IF EXISTS;
5 | DROP TABLE pets IF EXISTS;
6 | DROP TABLE types IF EXISTS;
7 | DROP TABLE owners IF EXISTS;
8 |
9 |
10 | CREATE TABLE vets (
11 | id INTEGER IDENTITY PRIMARY KEY,
12 | first_name VARCHAR(30),
13 | last_name VARCHAR(30)
14 | );
15 | CREATE INDEX vets_last_name ON vets (last_name);
16 |
17 | CREATE TABLE specialties (
18 | id INTEGER IDENTITY PRIMARY KEY,
19 | name VARCHAR(80)
20 | );
21 | CREATE INDEX specialties_name ON specialties (name);
22 |
23 | CREATE TABLE vet_specialties (
24 | vet_id INTEGER NOT NULL,
25 | specialty_id INTEGER NOT NULL
26 | );
27 | ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id);
28 | ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id);
29 |
30 | CREATE TABLE types (
31 | id INTEGER IDENTITY PRIMARY KEY,
32 | name VARCHAR(80)
33 | );
34 | CREATE INDEX types_name ON types (name);
35 |
36 | CREATE TABLE owners (
37 | id INTEGER IDENTITY PRIMARY KEY,
38 | first_name VARCHAR(30),
39 | last_name VARCHAR_IGNORECASE(30),
40 | address VARCHAR(255),
41 | city VARCHAR(80),
42 | telephone VARCHAR(20)
43 | );
44 | CREATE INDEX owners_last_name ON owners (last_name);
45 |
46 | CREATE TABLE pets (
47 | id INTEGER IDENTITY PRIMARY KEY,
48 | name VARCHAR(30),
49 | birth_date DATE,
50 | type_id INTEGER NOT NULL,
51 | owner_id INTEGER
52 | );
53 | ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id);
54 | ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id);
55 | CREATE INDEX pets_name ON pets (name);
56 |
57 | CREATE TABLE visits (
58 | id INTEGER IDENTITY PRIMARY KEY,
59 | pet_id INTEGER,
60 | visit_date DATE,
61 | description VARCHAR(255)
62 | );
63 | ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id);
64 | CREATE INDEX visits_pet_id ON visits (pet_id);
65 |
--------------------------------------------------------------------------------
/src/main/resources/templates/vets/vetList.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2019 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.samples.petclinic.system;
18 |
19 | import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
20 | import org.springframework.cache.annotation.EnableCaching;
21 | import org.springframework.context.annotation.Bean;
22 | import org.springframework.context.annotation.Configuration;
23 |
24 | import javax.cache.configuration.MutableConfiguration;
25 |
26 | /**
27 | * Cache configuration intended for caches providing the JCache API. This configuration
28 | * creates the used cache for the application and enables statistics that become
29 | * accessible via JMX.
30 | */
31 | @Configuration(proxyBeanMethods = false)
32 | @EnableCaching
33 | class CacheConfiguration {
34 |
35 | @Bean
36 | public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
37 | return cm -> cm.createCache("vets", cacheConfiguration());
38 | }
39 |
40 | /**
41 | * Create a simple configuration that enable statistics via the JCache programmatic
42 | * configuration API.
43 | *
44 | * Within the configuration object that is provided by the JCache API standard, there
45 | * is only a very limited set of configuration options. The really relevant
46 | * configuration options (like the size limit) must be set via a configuration
47 | * mechanism that is provided by the selected JCache implementation.
48 | */
49 | private javax.cache.configuration.Configuration