From 3e076c95d59f7908924886321feeffc976622f7c Mon Sep 17 00:00:00 2001
From: Mikel Garcia <122596907+mgarciaLKS@users.noreply.github.com>
Date: Thu, 27 Mar 2025 16:52:48 +0100
Subject: [PATCH 01/10] Update pom.xml
Signed-off-by: Mikel Garcia <122596907+mgarciaLKS@users.noreply.github.com>
---
pom.xml | 69 ++++++++++++++++++++++++++-------------------------------
1 file changed, 31 insertions(+), 38 deletions(-)
diff --git a/pom.xml b/pom.xml
index 28e3f119c..2f8bedadd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -250,45 +250,7 @@
-
- org.jacoco
- jacoco-maven-plugin
- ${jacoco.version}
-
-
-
- prepare-agent
-
- prepare-agent
-
-
-
-
- report
- verify
-
- report
-
-
- UTF-8
-
-
-
-
-
- report-aggregate
- verify
-
- report-aggregate
-
-
- ${project.build.directory}/site/jacoco
-
-
-
-
-
@@ -477,5 +439,36 @@
+
+ coverage
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.7
+
+
+ prepare-agent
+
+ prepare-agent
+
+
+
+ report
+
+ report
+
+
+
+ XML
+
+
+
+
+
+
+
+
From 83603cfb3d7412a5e6411b77e51f0213c8e9a527 Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Thu, 27 Mar 2025 16:54:07 +0100
Subject: [PATCH 02/10] Update Jenkinsfile
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
Jenkinsfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 76fed6f0d..5db60edc7 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -17,7 +17,7 @@ pipeline {
-v ./:/app \
-v "/home/jenkins/.m2":"/home/jenkins/.m2" \
-e JOB_ACTION="compile" \
- -e MAVEN_CMD="clean verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.branch.name=$SONAR_BRANCH" \
+ -e MAVEN_CMD="clean verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.branch.name=$SONAR_BRANCH" -Pcoverage \
$BUILD_IMAGE
'''
}
From 8eff6981f1b9a68f454e666777524b6cd07cf67a Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Thu, 27 Mar 2025 16:56:46 +0100
Subject: [PATCH 03/10] Update Jenkinsfile
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
Jenkinsfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 5db60edc7..1e8305982 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -17,7 +17,7 @@ pipeline {
-v ./:/app \
-v "/home/jenkins/.m2":"/home/jenkins/.m2" \
-e JOB_ACTION="compile" \
- -e MAVEN_CMD="clean verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.branch.name=$SONAR_BRANCH" -Pcoverage \
+ -e MAVEN_CMD="clean verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.token=$SONAR_TOKEN -Dsonar.branch.name=$SONAR_BRANCH -Pcoverage" \
$BUILD_IMAGE
'''
}
From b80781017874e5bc30c25476d2cafc2f4f2a0b93 Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:39:00 +0200
Subject: [PATCH 04/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../springframework/samples/petclinic/owner/Owner.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 675b2140e..2b22ad3f2 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -170,6 +170,14 @@ public class Owner extends Person {
Assert.notNull(pet, "Invalid Pet identifier!");
pet.addVisit(visit);
+
+ (req: Request, res: Response, next: NextFunction) => {
+ verifyPreLoginChallenges(req) // vuln-code-snippet hide-line
+ models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {
+ replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },
+ model: UserModel,
+ plain: true
+ })
}
}
From 6bd4cdbbe86011cab35dca94be03310bd6919c4f Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:45:30 +0200
Subject: [PATCH 05/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../springframework/samples/petclinic/owner/Owner.java | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 2b22ad3f2..675b2140e 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -170,14 +170,6 @@ public class Owner extends Person {
Assert.notNull(pet, "Invalid Pet identifier!");
pet.addVisit(visit);
-
- (req: Request, res: Response, next: NextFunction) => {
- verifyPreLoginChallenges(req) // vuln-code-snippet hide-line
- models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {
- replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },
- model: UserModel,
- plain: true
- })
}
}
From 34b1daa65f8167d7b8c362d8cb9519dcd5c3892c Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:49:48 +0200
Subject: [PATCH 06/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../samples/petclinic/owner/Owner.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 675b2140e..d02c9b97c 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -172,4 +172,18 @@ public class Owner extends Person {
pet.addVisit(visit);
}
+ public void forcedIssue() {
+ String vulnerableCode = "(req: Request, res: Response, next: NextFunction) => {\n" +
+ " verifyPreLoginChallenges(req) // vuln-code-snippet hide-line\n" +
+ " models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {\n" +
+ " replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },\n" +
+ " model: UserModel,\n" +
+ " plain: true\n" +
+ " })\n" +
+ "}";
+ System.out.println(vulnerableCode);
+ }
+}
+
+
}
From c9712a309ba7ec18afee1073d9579c84fcb48853 Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:50:57 +0200
Subject: [PATCH 07/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../org/springframework/samples/petclinic/owner/Owner.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index d02c9b97c..90ae31d07 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -184,6 +184,3 @@ public class Owner extends Person {
System.out.println(vulnerableCode);
}
}
-
-
-}
From e90e323130ff7bdf2074dd1a16082ade5aecf6da Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:54:19 +0200
Subject: [PATCH 08/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../samples/petclinic/owner/Owner.java | 252 ++++++++----------
1 file changed, 111 insertions(+), 141 deletions(-)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 90ae31d07..65d422a0e 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -1,18 +1,3 @@
-/*
- * Copyright 2012-2019 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
package org.springframework.samples.petclinic.owner;
import java.util.ArrayList;
@@ -36,151 +21,136 @@ import jakarta.validation.constraints.NotBlank;
/**
* Simple JavaBean domain object representing an owner.
*
- * @author Ken Krebs
- * @author Juergen Hoeller
- * @author Sam Brannen
- * @author Michael Isvy
- * @author Oliver Drotbohm
- * @author Wick Dynex
+ * (Autores omitidos para mayor claridad)
*/
@Entity
@Table(name = "owners")
public class Owner extends Person {
- @Column(name = "address")
- @NotBlank
- private String address;
+ @Column(name = "address")
+ @NotBlank
+ private String address;
- @Column(name = "city")
- @NotBlank
- private String city;
+ @Column(name = "city")
+ @NotBlank
+ private String city;
- @Column(name = "telephone")
- @NotBlank
- @Pattern(regexp = "\\d{10}", message = "Telephone must be a 10-digit number")
- private String telephone;
+ @Column(name = "telephone")
+ @NotBlank
+ @Pattern(regexp = "\\d{10}", message = "Telephone must be a 10-digit number")
+ private String telephone;
- @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
- @JoinColumn(name = "owner_id")
- @OrderBy("name")
- private final List pets = new ArrayList<>();
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "owner_id")
+ @OrderBy("name")
+ private final List pets = new ArrayList<>();
- public String getAddress() {
- return this.address;
- }
+ public String getAddress() {
+ return this.address;
+ }
- public void setAddress(String address) {
- this.address = address;
- }
+ public void setAddress(String address) {
+ this.address = address;
+ }
- public String getCity() {
- return this.city;
- }
+ public String getCity() {
+ return this.city;
+ }
- public void setCity(String city) {
- this.city = city;
- }
+ public void setCity(String city) {
+ this.city = city;
+ }
- public String getTelephone() {
- return this.telephone;
- }
+ public String getTelephone() {
+ return this.telephone;
+ }
- public void setTelephone(String telephone) {
- this.telephone = telephone;
- }
+ public void setTelephone(String telephone) {
+ this.telephone = telephone;
+ }
- public List getPets() {
- return this.pets;
- }
+ public List getPets() {
+ return this.pets;
+ }
- public void addPet(Pet pet) {
- if (pet.isNew()) {
- getPets().add(pet);
- }
- }
+ public void addPet(Pet pet) {
+ if (pet.isNew()) {
+ getPets().add(pet);
+ }
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- * @param name to test
- * @return the Pet with the given name, or null if no such Pet exists for this Owner
- */
- public Pet getPet(String name) {
- return getPet(name, false);
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ *
+ * @param name to test
+ * @return the Pet with the given name, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(String name) {
+ return getPet(name, false);
+ }
- /**
- * Return the Pet with the given id, or null if none found for this Owner.
- * @param id to test
- * @return the Pet with the given id, or null if no such Pet exists for this Owner
- */
- public Pet getPet(Integer id) {
- for (Pet pet : getPets()) {
- if (!pet.isNew()) {
- Integer compId = pet.getId();
- if (compId.equals(id)) {
- return pet;
- }
- }
- }
- return null;
- }
+ /**
+ * Return the Pet with the given id, or null if none found for this Owner.
+ *
+ * @param id to test
+ * @return the Pet with the given id, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(Integer id) {
+ for (Pet pet : getPets()) {
+ if (!pet.isNew()) {
+ Integer compId = pet.getId();
+ if (compId.equals(id)) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- * @param name to test
- * @param ignoreNew whether to ignore new pets (pets that are not saved yet)
- * @return the Pet with the given name, or null if no such Pet exists for this Owner
- */
- public Pet getPet(String name, boolean ignoreNew) {
- for (Pet pet : getPets()) {
- String compName = pet.getName();
- if (compName != null && compName.equalsIgnoreCase(name)) {
- if (!ignoreNew || !pet.isNew()) {
- return pet;
- }
- }
- }
- return null;
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ *
+ * @param name to test
+ * @param ignoreNew whether to ignore new pets (pets that are not saved yet)
+ * @return the Pet with the given name, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(String name, boolean ignoreNew) {
+ for (Pet pet : getPets()) {
+ String compName = pet.getName();
+ if (compName != null && compName.equalsIgnoreCase(name)) {
+ if (!ignoreNew || !pet.isNew()) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
- @Override
- public String toString() {
- return new ToStringCreator(this).append("id", this.getId())
- .append("new", this.isNew())
- .append("lastName", this.getLastName())
- .append("firstName", this.getFirstName())
- .append("address", this.address)
- .append("city", this.city)
- .append("telephone", this.telephone)
- .toString();
- }
+ @Override
+ public String toString() {
+ return new ToStringCreator(this)
+ .append("id", this.getId())
+ .append("new", this.isNew())
+ .append("lastName", this.getLastName())
+ .append("firstName", this.getFirstName())
+ .append("address", this.address)
+ .append("city", this.city)
+ .append("telephone", this.telephone)
+ .toString();
+ }
- /**
- * Adds the given {@link Visit} to the {@link Pet} with the given identifier.
- * @param petId the identifier of the {@link Pet}, must not be {@literal null}.
- * @param visit the visit to add, must not be {@literal null}.
- */
- public void addVisit(Integer petId, Visit visit) {
-
- Assert.notNull(petId, "Pet identifier must not be null!");
- Assert.notNull(visit, "Visit must not be null!");
-
- Pet pet = getPet(petId);
-
- Assert.notNull(pet, "Invalid Pet identifier!");
-
- pet.addVisit(visit);
- }
-
- public void forcedIssue() {
- String vulnerableCode = "(req: Request, res: Response, next: NextFunction) => {\n" +
- " verifyPreLoginChallenges(req) // vuln-code-snippet hide-line\n" +
- " models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {\n" +
- " replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },\n" +
- " model: UserModel,\n" +
- " plain: true\n" +
- " })\n" +
- "}";
- System.out.println(vulnerableCode);
- }
+ /**
+ * Método dummy para forzar que SonarQube detecte la siguiente ISSUE:
+ * "Change this code to not construct SQL queries directly from user-controlled data".
+ *
+ * NOTA: Este método NO se utiliza en la lógica del negocio y solo está presente
+ * para que el análisis estático detecte el patrón vulnerable.
+ *
+ * @param userInput entrada controlada por el usuario
+ * @return Consulta SQL construida de forma insegura
+ */
+ public String buildVulnerableQuery(String userInput) {
+ String vulnerableQuery = "SELECT * FROM Users WHERE email = '" + userInput + "'";
+ return vulnerableQuery;
+ }
}
From 473c3a694e83f49bed8692745d1d333ee409f6b3 Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:55:48 +0200
Subject: [PATCH 09/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../samples/petclinic/owner/Owner.java | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 65d422a0e..a0e6d3c5b 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -138,19 +138,4 @@ public class Owner extends Person {
.append("telephone", this.telephone)
.toString();
}
-
- /**
- * Método dummy para forzar que SonarQube detecte la siguiente ISSUE:
- * "Change this code to not construct SQL queries directly from user-controlled data".
- *
- * NOTA: Este método NO se utiliza en la lógica del negocio y solo está presente
- * para que el análisis estático detecte el patrón vulnerable.
- *
- * @param userInput entrada controlada por el usuario
- * @return Consulta SQL construida de forma insegura
- */
- public String buildVulnerableQuery(String userInput) {
- String vulnerableQuery = "SELECT * FROM Users WHERE email = '" + userInput + "'";
- return vulnerableQuery;
- }
}
From 56b3b3148efe7c82a7f4ee02aa46f5f6d8775218 Mon Sep 17 00:00:00 2001
From: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
Date: Mon, 31 Mar 2025 11:56:29 +0200
Subject: [PATCH 10/10] Update Owner.java
Signed-off-by: AulaEmpresaLKS <129507941+AulaEmpresaLKS@users.noreply.github.com>
---
.../samples/petclinic/owner/Owner.java | 228 ++++++++++--------
1 file changed, 131 insertions(+), 97 deletions(-)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index a0e6d3c5b..675b2140e 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2012-2019 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.springframework.samples.petclinic.owner;
import java.util.ArrayList;
@@ -21,121 +36,140 @@ import jakarta.validation.constraints.NotBlank;
/**
* Simple JavaBean domain object representing an owner.
*
- * (Autores omitidos para mayor claridad)
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ * @author Michael Isvy
+ * @author Oliver Drotbohm
+ * @author Wick Dynex
*/
@Entity
@Table(name = "owners")
public class Owner extends Person {
- @Column(name = "address")
- @NotBlank
- private String address;
+ @Column(name = "address")
+ @NotBlank
+ private String address;
- @Column(name = "city")
- @NotBlank
- private String city;
+ @Column(name = "city")
+ @NotBlank
+ private String city;
- @Column(name = "telephone")
- @NotBlank
- @Pattern(regexp = "\\d{10}", message = "Telephone must be a 10-digit number")
- private String telephone;
+ @Column(name = "telephone")
+ @NotBlank
+ @Pattern(regexp = "\\d{10}", message = "Telephone must be a 10-digit number")
+ private String telephone;
- @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
- @JoinColumn(name = "owner_id")
- @OrderBy("name")
- private final List pets = new ArrayList<>();
+ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "owner_id")
+ @OrderBy("name")
+ private final List pets = new ArrayList<>();
- public String getAddress() {
- return this.address;
- }
+ public String getAddress() {
+ return this.address;
+ }
- public void setAddress(String address) {
- this.address = address;
- }
+ public void setAddress(String address) {
+ this.address = address;
+ }
- public String getCity() {
- return this.city;
- }
+ public String getCity() {
+ return this.city;
+ }
- public void setCity(String city) {
- this.city = city;
- }
+ public void setCity(String city) {
+ this.city = city;
+ }
- public String getTelephone() {
- return this.telephone;
- }
+ public String getTelephone() {
+ return this.telephone;
+ }
- public void setTelephone(String telephone) {
- this.telephone = telephone;
- }
+ public void setTelephone(String telephone) {
+ this.telephone = telephone;
+ }
- public List getPets() {
- return this.pets;
- }
+ public List getPets() {
+ return this.pets;
+ }
- public void addPet(Pet pet) {
- if (pet.isNew()) {
- getPets().add(pet);
- }
- }
+ public void addPet(Pet pet) {
+ if (pet.isNew()) {
+ getPets().add(pet);
+ }
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- *
- * @param name to test
- * @return the Pet with the given name, or null if no such Pet exists for this Owner
- */
- public Pet getPet(String name) {
- return getPet(name, false);
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @return the Pet with the given name, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(String name) {
+ return getPet(name, false);
+ }
- /**
- * Return the Pet with the given id, or null if none found for this Owner.
- *
- * @param id to test
- * @return the Pet with the given id, or null if no such Pet exists for this Owner
- */
- public Pet getPet(Integer id) {
- for (Pet pet : getPets()) {
- if (!pet.isNew()) {
- Integer compId = pet.getId();
- if (compId.equals(id)) {
- return pet;
- }
- }
- }
- return null;
- }
+ /**
+ * Return the Pet with the given id, or null if none found for this Owner.
+ * @param id to test
+ * @return the Pet with the given id, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(Integer id) {
+ for (Pet pet : getPets()) {
+ if (!pet.isNew()) {
+ Integer compId = pet.getId();
+ if (compId.equals(id)) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
- /**
- * Return the Pet with the given name, or null if none found for this Owner.
- *
- * @param name to test
- * @param ignoreNew whether to ignore new pets (pets that are not saved yet)
- * @return the Pet with the given name, or null if no such Pet exists for this Owner
- */
- public Pet getPet(String name, boolean ignoreNew) {
- for (Pet pet : getPets()) {
- String compName = pet.getName();
- if (compName != null && compName.equalsIgnoreCase(name)) {
- if (!ignoreNew || !pet.isNew()) {
- return pet;
- }
- }
- }
- return null;
- }
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @param ignoreNew whether to ignore new pets (pets that are not saved yet)
+ * @return the Pet with the given name, or null if no such Pet exists for this Owner
+ */
+ public Pet getPet(String name, boolean ignoreNew) {
+ for (Pet pet : getPets()) {
+ String compName = pet.getName();
+ if (compName != null && compName.equalsIgnoreCase(name)) {
+ if (!ignoreNew || !pet.isNew()) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringCreator(this).append("id", this.getId())
+ .append("new", this.isNew())
+ .append("lastName", this.getLastName())
+ .append("firstName", this.getFirstName())
+ .append("address", this.address)
+ .append("city", this.city)
+ .append("telephone", this.telephone)
+ .toString();
+ }
+
+ /**
+ * Adds the given {@link Visit} to the {@link Pet} with the given identifier.
+ * @param petId the identifier of the {@link Pet}, must not be {@literal null}.
+ * @param visit the visit to add, must not be {@literal null}.
+ */
+ public void addVisit(Integer petId, Visit visit) {
+
+ Assert.notNull(petId, "Pet identifier must not be null!");
+ Assert.notNull(visit, "Visit must not be null!");
+
+ Pet pet = getPet(petId);
+
+ Assert.notNull(pet, "Invalid Pet identifier!");
+
+ pet.addVisit(visit);
+ }
- @Override
- public String toString() {
- return new ToStringCreator(this)
- .append("id", this.getId())
- .append("new", this.isNew())
- .append("lastName", this.getLastName())
- .append("firstName", this.getFirstName())
- .append("address", this.address)
- .append("city", this.city)
- .append("telephone", this.telephone)
- .toString();
- }
}