diff --git a/pom.xml b/pom.xml
index e4e74747a..ed213a1ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,13 @@
+
+
+ org.modelmapper.extensions
+ modelmapper-spring
+ 2.3.0
+
+
com.h2database
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java
similarity index 73%
rename from src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
rename to src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java
index 79aa4cd9b..35ac779e1 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
+++ b/src/main/java/org/springframework/samples/petclinic/controller/OwnerController.java
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.owner;
+package org.springframework.samples.petclinic.controller;
-import org.springframework.samples.petclinic.visit.VisitRepository;
+import org.springframework.samples.petclinic.dto.*;
+import org.springframework.samples.petclinic.service.OwnerService;
+import org.springframework.samples.petclinic.service.VisitService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
@@ -35,19 +37,19 @@ import java.util.Map;
* @author Ken Krebs
* @author Arjen Poutsma
* @author Michael Isvy
+ * @author Paul-Emmanuel DOS SANTOS FACAO
*/
@Controller
class OwnerController {
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
- private final OwnerRepository owners;
+ private final OwnerService ownerService;
+ private final VisitService visitService;
- private VisitRepository visits;
-
- public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
- this.owners = clinicService;
- this.visits = visits;
+ OwnerController(OwnerService ownerService, VisitService visitService) {
+ this.ownerService = ownerService;
+ this.visitService = visitService;
}
@InitBinder
@@ -57,30 +59,30 @@ class OwnerController {
@GetMapping("/owners/new")
public String initCreationForm(Map model) {
- Owner owner = new Owner();
+ OwnerDTO owner = new OwnerDTO();
model.put("owner", owner);
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/owners/new")
- public String processCreationForm(@Valid Owner owner, BindingResult result) {
+ public String processCreationForm(@Valid OwnerDTO owner, BindingResult result) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
}
else {
- this.owners.save(owner);
+ this.ownerService.save(owner);
return "redirect:/owners/" + owner.getId();
}
}
@GetMapping("/owners/find")
public String initFindForm(Map model) {
- model.put("owner", new Owner());
+ model.put("owner", new OwnerDTO());
return "owners/findOwners";
}
@GetMapping("/owners")
- public String processFindForm(Owner owner, BindingResult result, Map model) {
+ public String processFindForm(OwnerDTO owner, BindingResult result, Map model) {
// allow parameterless GET request for /owners to return all records
if (owner.getLastName() == null) {
@@ -88,7 +90,7 @@ class OwnerController {
}
// find owners by last name
- Collection results = this.owners.findByLastName(owner.getLastName());
+ Collection results = this.ownerService.findByLastName(owner.getLastName());
if (results.isEmpty()) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
@@ -108,20 +110,20 @@ class OwnerController {
@GetMapping("/owners/{ownerId}/edit")
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
- Owner owner = this.owners.findById(ownerId);
- model.addAttribute(owner);
+ OwnerDTO ownerDTO = this.ownerService.findById(ownerId);
+ model.addAttribute(ownerDTO);
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/owners/{ownerId}/edit")
- public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result,
+ public String processUpdateOwnerForm(@Valid OwnerDTO owner, BindingResult result,
@PathVariable("ownerId") int ownerId) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
}
else {
owner.setId(ownerId);
- this.owners.save(owner);
+ this.ownerService.save(owner);
return "redirect:/owners/{ownerId}";
}
}
@@ -134,10 +136,12 @@ class OwnerController {
@GetMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owners/ownerDetails");
- Owner owner = this.owners.findById(ownerId);
- for (Pet pet : owner.getPets()) {
- pet.setVisitsInternal(visits.findByPetId(pet.getId()));
+ OwnerDTO owner = this.ownerService.findById(ownerId);
+
+ for (PetDTO petDTO : owner.getPets()) {
+ petDTO.setVisitsInternal(visitService.findByPetId(petDTO.getId()));
}
+
mav.addObject(owner);
return mav;
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java
similarity index 60%
rename from src/main/java/org/springframework/samples/petclinic/owner/PetController.java
rename to src/main/java/org/springframework/samples/petclinic/controller/PetController.java
index a55e599af..b8f6b945b 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
+++ b/src/main/java/org/springframework/samples/petclinic/controller/PetController.java
@@ -13,8 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.owner;
+package org.springframework.samples.petclinic.controller;
+import org.springframework.samples.petclinic.dto.OwnerDTO;
+import org.springframework.samples.petclinic.dto.PetDTO;
+import org.springframework.samples.petclinic.dto.PetTypeDTO;
+import org.springframework.samples.petclinic.owner.PetValidator;
+import org.springframework.samples.petclinic.service.OwnerService;
+import org.springframework.samples.petclinic.service.PetService;
+import org.springframework.samples.petclinic.service.PetTypeService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
@@ -29,6 +36,7 @@ import java.util.Collection;
* @author Juergen Hoeller
* @author Ken Krebs
* @author Arjen Poutsma
+ * @author Paul-Emmanuel DOS SANTOS FACAO
*/
@Controller
@RequestMapping("/owners/{ownerId}")
@@ -36,23 +44,25 @@ class PetController {
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
- private final PetRepository pets;
+ private final OwnerService ownerService;
+ private final PetService petService;
+ private final PetTypeService petTypeService;
- private final OwnerRepository owners;
-
- public PetController(PetRepository pets, OwnerRepository owners) {
- this.pets = pets;
- this.owners = owners;
+ PetController(OwnerService ownerService, PetService petService, PetTypeService petTypeService) {
+ this.ownerService = ownerService;
+ this.petService = petService;
+ this.petTypeService = petTypeService;
}
+
@ModelAttribute("types")
- public Collection populatePetTypes() {
- return this.pets.findPetTypes();
+ public Collection populatePetTypes() {
+ return this.petTypeService.findPetTypes();
}
@ModelAttribute("owner")
- public Owner findOwner(@PathVariable("ownerId") int ownerId) {
- return this.owners.findById(ownerId);
+ public OwnerDTO findOwner(@PathVariable("ownerId") int ownerId) {
+ return this.ownerService.findById(ownerId);
}
@InitBinder("owner")
@@ -66,38 +76,38 @@ class PetController {
}
@GetMapping("/pets/new")
- public String initCreationForm(Owner owner, ModelMap model) {
- Pet pet = new Pet();
+ public String initCreationForm(OwnerDTO owner, ModelMap model) {
+ PetDTO pet = new PetDTO();
owner.addPet(pet);
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/pets/new")
- public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
- if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
+ public String processCreationForm(OwnerDTO ownerDTO, @Valid PetDTO pet, BindingResult result, ModelMap model) {
+ if (StringUtils.hasLength(pet.getName()) && pet.isNew() && ownerDTO.getPet(pet.getName(), true) != null) {
result.rejectValue("name", "duplicate", "already exists");
}
- owner.addPet(pet);
+ ownerDTO.addPet(pet);
if (result.hasErrors()) {
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
}
else {
- this.pets.save(pet);
+ this.petService.save(pet);
return "redirect:/owners/{ownerId}";
}
}
@GetMapping("/pets/{petId}/edit")
public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
- Pet pet = this.pets.findById(petId);
+ PetDTO pet = this.petService.findById(petId);
model.put("pet", pet);
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
}
@PostMapping("/pets/{petId}/edit")
- public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
+ public String processUpdateForm(@Valid PetDTO pet, BindingResult result, OwnerDTO owner, ModelMap model) {
if (result.hasErrors()) {
pet.setOwner(owner);
model.put("pet", pet);
@@ -105,7 +115,7 @@ class PetController {
}
else {
owner.addPet(pet);
- this.pets.save(pet);
+ this.petService.save(pet);
return "redirect:/owners/{ownerId}";
}
}
diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java
similarity index 69%
rename from src/main/java/org/springframework/samples/petclinic/vet/VetController.java
rename to src/main/java/org/springframework/samples/petclinic/controller/VetController.java
index fb5e321ba..9ace51d26 100644
--- a/src/main/java/org/springframework/samples/petclinic/vet/VetController.java
+++ b/src/main/java/org/springframework/samples/petclinic/controller/VetController.java
@@ -13,8 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.vet;
+package org.springframework.samples.petclinic.controller;
+import org.springframework.samples.petclinic.dto.VetsDTO;
+import org.springframework.samples.petclinic.service.VetService;
+import org.springframework.samples.petclinic.vet.Vets;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -26,32 +29,34 @@ import java.util.Map;
* @author Mark Fisher
* @author Ken Krebs
* @author Arjen Poutsma
+ * @author Paul-Emmanuel DOS SANTOS FACAO
*/
@Controller
class VetController {
- private final VetRepository vets;
+ private final VetService vetService;
- public VetController(VetRepository clinicService) {
- this.vets = clinicService;
+ VetController(VetService vetService) {
+ this.vetService = vetService;
}
+
@GetMapping("/vets.html")
public String showVetList(Map model) {
// Here we are returning an object of type 'Vets' rather than a collection of Vet
// objects so it is simpler for Object-Xml mapping
- Vets vets = new Vets();
- vets.getVetList().addAll(this.vets.findAll());
+ VetsDTO vets = new VetsDTO();
+ vets.getVetList().addAll(this.vetService.findAll());
model.put("vets", vets);
return "vets/vetList";
}
@GetMapping({ "/vets" })
- public @ResponseBody Vets showResourcesVetList() {
+ public @ResponseBody VetsDTO showResourcesVetList() {
// Here we are returning an object of type 'Vets' rather than a collection of Vet
// objects so it is simpler for JSon/Object mapping
- Vets vets = new Vets();
- vets.getVetList().addAll(this.vets.findAll());
+ VetsDTO vets = new VetsDTO();
+ vets.getVetList().addAll(this.vetService.findAll());
return vets;
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java
similarity index 72%
rename from src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
rename to src/main/java/org/springframework/samples/petclinic/controller/VisitController.java
index 375980312..dd8bc1330 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
+++ b/src/main/java/org/springframework/samples/petclinic/controller/VisitController.java
@@ -13,14 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.owner;
+package org.springframework.samples.petclinic.controller;
import java.util.Map;
import javax.validation.Valid;
+import org.springframework.samples.petclinic.dto.PetDTO;
+import org.springframework.samples.petclinic.dto.VisitDTO;
+import org.springframework.samples.petclinic.service.PetService;
+import org.springframework.samples.petclinic.service.VisitService;
import org.springframework.samples.petclinic.visit.Visit;
-import org.springframework.samples.petclinic.visit.VisitRepository;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
@@ -36,19 +39,20 @@ import org.springframework.web.bind.annotation.PostMapping;
* @author Arjen Poutsma
* @author Michael Isvy
* @author Dave Syer
+ * @author Paul-Emmanuel DOS SANTOS FACAO
*/
@Controller
class VisitController {
- private final VisitRepository visits;
+ private final VisitService visitService;
+ private final PetService petService;
- private final PetRepository pets;
-
- public VisitController(VisitRepository visits, PetRepository pets) {
- this.visits = visits;
- this.pets = pets;
+ VisitController(VisitService visitService, PetService petService) {
+ this.visitService = visitService;
+ this.petService = petService;
}
+
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
@@ -62,11 +66,11 @@ class VisitController {
* @return Pet
*/
@ModelAttribute("visit")
- public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map model) {
- Pet pet = this.pets.findById(petId);
- pet.setVisitsInternal(this.visits.findByPetId(petId));
+ public VisitDTO loadPetWithVisit(@PathVariable("petId") int petId, Map model) {
+ PetDTO pet = this.petService.findById(petId);
+ pet.setVisitsInternal(this.visitService.findByPetId(petId));
model.put("pet", pet);
- Visit visit = new Visit();
+ VisitDTO visit = new VisitDTO();
pet.addVisit(visit);
return visit;
}
@@ -79,12 +83,12 @@ class VisitController {
// Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
@PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
- public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
+ public String processNewVisitForm(@Valid VisitDTO visit, BindingResult result) {
if (result.hasErrors()) {
return "pets/createOrUpdateVisitForm";
}
else {
- this.visits.save(visit);
+ this.visitService.save(visit);
return "redirect:/owners/{ownerId}";
}
}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java
new file mode 100644
index 000000000..1aa04af7a
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/BaseDTO.java
@@ -0,0 +1,41 @@
+/*
+ * 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.dto;
+
+import java.io.Serializable;
+
+/**
+ * Simple Data Transfert Object with an id property. Used as a base class for DTO
+ * needing this property.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class BaseDTO implements Serializable {
+
+ private Integer id;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public boolean isNew() {
+ return this.id == null;
+ }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java
new file mode 100644
index 000000000..345a192e2
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/NamedDTO.java
@@ -0,0 +1,42 @@
+/*
+ * 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.dto;
+
+
+/**
+ * Simple Data Transfert Object with a name property to BaseDTO
. Used as
+ * a base class for DTOs needing these properties.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class NamedDTO extends BaseDTO {
+
+ private String name;
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return this.getName();
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java
new file mode 100644
index 000000000..c6bd4225e
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/OwnerDTO.java
@@ -0,0 +1,130 @@
+/*
+ * 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.dto;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+import org.springframework.core.style.ToStringCreator;
+
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotEmpty;
+import java.util.*;
+
+/**
+ * Simple Data Transfert Object representing a owner.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class OwnerDTO extends PersonDTO {
+
+ @NotEmpty
+ private String address;
+
+ @NotEmpty
+ private String city;
+
+ @NotEmpty
+ @Digits(fraction = 0, integer = 10)
+ private String telephone;
+
+ private Set pets;
+
+ public String getAddress() {
+ return this.address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getCity() {
+ return this.city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getTelephone() {
+ return this.telephone;
+ }
+
+ public void setTelephone(String telephone) {
+ this.telephone = telephone;
+ }
+
+ protected Set getPetsInternal() {
+ if (this.pets == null) {
+ this.pets = new HashSet<>();
+ }
+ return this.pets;
+ }
+
+ protected void setPetsInternal(Set pets) {
+ this.pets = pets;
+ }
+
+ public List getPets() {
+ List sortedPets = new ArrayList<>(getPetsInternal());
+ PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
+ return Collections.unmodifiableList(sortedPets);
+ }
+
+ public void addPet(PetDTO pet) {
+ if (pet.isNew()) {
+ getPetsInternal().add(pet);
+ }
+ pet.setOwner(this);
+ }
+
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @return true if pet name is already in use
+ */
+ public PetDTO getPet(String name) {
+ return getPet(name, false);
+ }
+
+ /**
+ * Return the Pet with the given name, or null if none found for this Owner.
+ * @param name to test
+ * @return true if pet name is already in use
+ */
+ public PetDTO getPet(String name, boolean ignoreNew) {
+ name = name.toLowerCase();
+ for (PetDTO pet : getPetsInternal()) {
+ if (!ignoreNew || !pet.isNew()) {
+ String compName = pet.getName();
+ compName = compName.toLowerCase();
+ if (compName.equals(name)) {
+ return pet;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringCreator(this)
+
+ .append("id", this.getId()).append("new", this.isNew()).append("lastName", this.getLastName())
+ .append("firstName", this.getFirstName()).append("address", this.address).append("city", this.city)
+ .append("telephone", this.telephone).toString();
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java
new file mode 100644
index 000000000..44d4f1faf
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/PersonDTO.java
@@ -0,0 +1,47 @@
+/*
+ * 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.dto;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * Simple Data Transfert Object representing a person.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class PersonDTO extends BaseDTO {
+
+ @NotEmpty
+ private String firstName;
+ @NotEmpty
+ private String lastName;
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java
new file mode 100644
index 000000000..a5000e27a
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/PetDTO.java
@@ -0,0 +1,88 @@
+/*
+ * 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.dto;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.samples.petclinic.owner.PetType;
+
+import java.time.LocalDate;
+import java.util.*;
+
+/**
+ * Simple Data Transfert Object representing a pet.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class PetDTO extends NamedDTO {
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate birthDate;
+
+ private PetType type;
+
+ private OwnerDTO owner;
+
+ private Set visits = new LinkedHashSet<>();
+
+ public void setBirthDate(LocalDate birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public LocalDate getBirthDate() {
+ return this.birthDate;
+ }
+
+ public PetType getType() {
+ return this.type;
+ }
+
+ public void setType(PetType type) {
+ this.type = type;
+ }
+
+ public OwnerDTO getOwnerDTO() {
+ return owner;
+ }
+
+ public void setOwner(OwnerDTO owner) {
+ this.owner = owner;
+ }
+
+ protected Set getVisitsInternal() {
+ if (this.visits == null) {
+ this.visits = new HashSet<>();
+ }
+ return this.visits;
+ }
+
+ public void setVisitsInternal(Collection visits) {
+ this.visits = new LinkedHashSet<>(visits);
+ }
+
+ public List getVisits() {
+ List sortedVisits = new ArrayList<>(getVisitsInternal());
+ PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
+ return Collections.unmodifiableList(sortedVisits);
+ }
+
+ public void addVisit(VisitDTO visit) {
+ getVisitsInternal().add(visit);
+ visit.setPetId(this.getId());
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java
new file mode 100644
index 000000000..54d771c7f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/PetTypeDTO.java
@@ -0,0 +1,10 @@
+package org.springframework.samples.petclinic.dto;
+
+/**
+ * Simple Data Transfert Object representing PetType.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class PetTypeDTO extends NamedDTO {
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java
new file mode 100644
index 000000000..d209a511a
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/SpecialtyDTO.java
@@ -0,0 +1,12 @@
+package org.springframework.samples.petclinic.dto;
+
+import java.io.Serializable;
+
+/**
+ * Simple Data Transfert Object representing a list of specialities.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class SpecialtyDTO extends NamedDTO implements Serializable {
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java
new file mode 100644
index 000000000..048598218
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/VetDTO.java
@@ -0,0 +1,60 @@
+/*
+ * 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.dto;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+import org.springframework.samples.petclinic.vet.Specialty;
+
+import javax.xml.bind.annotation.XmlElement;
+import java.util.*;
+
+/**
+ * Simple Data Transfert Object representing a vet.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class VetDTO extends PersonDTO {
+
+ private Set specialties;
+
+ protected Set getSpecialtiesInternal() {
+ if (this.specialties == null) {
+ this.specialties = new HashSet<>();
+ }
+ return this.specialties;
+ }
+
+ protected void setSpecialtiesInternal(Set specialties) {
+ this.specialties = specialties;
+ }
+
+ @XmlElement
+ public List getSpecialties() {
+ List sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
+ PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
+ return Collections.unmodifiableList(sortedSpecs);
+ }
+
+ public int getNrOfSpecialties() {
+ return getSpecialtiesInternal().size();
+ }
+
+ public void addSpecialty(Specialty specialty) {
+ getSpecialtiesInternal().add(specialty);
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java
new file mode 100644
index 000000000..aea942f58
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/VetsDTO.java
@@ -0,0 +1,37 @@
+/*
+ * 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.dto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple Data Transfert Object representing a list of veterinarians.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class VetsDTO {
+
+ private List vets;
+
+ public List getVetList() {
+ if (vets == null) {
+ vets = new ArrayList<>();
+ }
+ return vets;
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java
new file mode 100644
index 000000000..835b0dd75
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/dto/VisitDTO.java
@@ -0,0 +1,68 @@
+/*
+ * 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.dto;
+
+import org.springframework.format.annotation.DateTimeFormat;
+import javax.validation.constraints.NotEmpty;
+import java.time.LocalDate;
+
+/**
+ * Simple Data Transfert Object representing a visit.
+ *
+ * @author Paul-Emmanuel DOS SANTOS FACAO
+ */
+public class VisitDTO extends BaseDTO {
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd")
+ private LocalDate date;
+
+ @NotEmpty
+ private String description;
+
+ private Integer petId;
+
+ /**
+ * Creates a new instance of Visit for the current date
+ */
+ public VisitDTO() {
+ this.date = LocalDate.now();
+ }
+
+ public LocalDate getDate() {
+ return this.date;
+ }
+
+ public void setDate(LocalDate date) {
+ this.date = date;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Integer getPetId() {
+ return this.petId;
+ }
+
+ public void setPetId(Integer petId) {
+ this.petId = petId;
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
index 4940bcb38..d96062c49 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetTypeFormatter.java
@@ -21,6 +21,7 @@ import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.Formatter;
+import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.stereotype.Component;
/**
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
similarity index 95%
rename from src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
rename to src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
index 0613e928a..16ac813d8 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/OwnerRepository.java
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.owner;
+package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
+import org.springframework.samples.petclinic.owner.Owner;
import org.springframework.transaction.annotation.Transactional;
/**
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
similarity index 91%
rename from src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java
rename to src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
index 9d25b095b..74a4ab140 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/PetRepository.java
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.owner;
+package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
+import org.springframework.samples.petclinic.owner.Pet;
+import org.springframework.samples.petclinic.owner.PetType;
import org.springframework.transaction.annotation.Transactional;
/**
diff --git a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
similarity index 93%
rename from src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java
rename to src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
index 549b1c229..a6eb67935 100644
--- a/src/main/java/org/springframework/samples/petclinic/vet/VetRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/VetRepository.java
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.vet;
+package org.springframework.samples.petclinic.repository;
import java.util.Collection;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
+import org.springframework.samples.petclinic.vet.Vet;
import org.springframework.transaction.annotation.Transactional;
/**
diff --git a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
similarity index 93%
rename from src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java
rename to src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
index d5a3334c6..5b680916f 100644
--- a/src/main/java/org/springframework/samples/petclinic/visit/VisitRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/repository/VisitRepository.java
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.samples.petclinic.visit;
+package org.springframework.samples.petclinic.repository;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
+import org.springframework.samples.petclinic.visit.Visit;
/**
* Repository class for Visit
domain objects All method names are compliant
diff --git a/src/main/java/org/springframework/samples/petclinic/service/BaseService.java b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java
new file mode 100644
index 000000000..93e3a2db8
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/BaseService.java
@@ -0,0 +1,10 @@
+package org.springframework.samples.petclinic.service;
+
+import java.util.Collection;
+
+public interface BaseService {
+ public E dtoToEntity(D dto);
+ public D entityToDTO(E entity);
+ public Collection entitiesToDTOS(Collection entities);
+ public Collection dtosToEntities(Collection dtos);
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java
new file mode 100644
index 000000000..fb3837b6a
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/OwnerService.java
@@ -0,0 +1,68 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.OwnerDTO;
+import org.springframework.samples.petclinic.owner.Owner;
+import org.springframework.samples.petclinic.repository.OwnerRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("OwnerService")
+public class OwnerService implements BaseService{
+
+ private final OwnerRepository ownerRepository;
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ public OwnerService(OwnerRepository ownerRepository) {
+ this.ownerRepository = ownerRepository;
+ }
+
+ @Override
+ public Owner dtoToEntity(OwnerDTO dto) {
+ return modelMapper.map(dto, Owner.class);
+ }
+
+ @Override
+ public OwnerDTO entityToDTO(Owner entity) {
+ return modelMapper.map(entity, OwnerDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(Owner entity: entities) {
+ dtos.add(entityToDTO(entity));
+ }
+
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(OwnerDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+
+ public void save(OwnerDTO ownerDTO) {
+ Owner owner = dtoToEntity(ownerDTO);
+ ownerRepository.save(owner);
+ }
+
+ public Collection findByLastName(String lastName) {
+ Collection owners = ownerRepository.findByLastName(lastName);
+ return entitiesToDTOS(owners);
+ }
+
+ public OwnerDTO findById(int ownerId) {
+ Owner owner = ownerRepository.findById(ownerId);
+ return entityToDTO(owner);
+ }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetService.java b/src/main/java/org/springframework/samples/petclinic/service/PetService.java
new file mode 100644
index 000000000..117e60752
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/PetService.java
@@ -0,0 +1,63 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.PetDTO;
+import org.springframework.samples.petclinic.owner.Pet;
+import org.springframework.samples.petclinic.repository.PetRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("PetService")
+public class PetService implements BaseService{
+ private final PetRepository petRepository;
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ public PetService(PetRepository petRepository) {
+ this.petRepository = petRepository;
+ }
+
+ @Override
+ public Pet dtoToEntity(PetDTO dto) {
+ return modelMapper.map(dto, Pet.class);
+ }
+
+ @Override
+ public PetDTO entityToDTO(Pet entity) {
+ return modelMapper.map(entity, PetDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(Pet entity:entities) {
+ dtos.add(entityToDTO(entity));
+ }
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(PetDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+
+ public void save(PetDTO petDTO) {
+ Pet pet = dtoToEntity(petDTO);
+ petRepository.save(pet);
+ }
+
+ public PetDTO findById(int petId) {
+ Pet pet = petRepository.findById(petId);
+ return entityToDTO(pet);
+ }
+
+}
+
diff --git a/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java
new file mode 100644
index 000000000..7623d6cab
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/PetTypeService.java
@@ -0,0 +1,59 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.PetTypeDTO;
+import org.springframework.samples.petclinic.owner.PetType;
+import org.springframework.samples.petclinic.repository.PetRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("PerTypeService")
+public class PetTypeService implements BaseService{
+ private final PetRepository petRepository;
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ public PetTypeService(PetRepository petRepository) {
+ this.petRepository = petRepository;
+ }
+
+ @Override
+ public PetType dtoToEntity(PetTypeDTO dto) {
+ return modelMapper.map(dto, PetType.class);
+ }
+
+ @Override
+ public PetTypeDTO entityToDTO(PetType entity) {
+ return modelMapper.map(entity, PetTypeDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(PetType entity : entities) {
+ dtos.add(entityToDTO(entity));
+ }
+
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(PetTypeDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+
+
+ public Collection findPetTypes() {
+ Collection petTypes = petRepository.findPetTypes();
+ return entitiesToDTOS(petTypes);
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java
new file mode 100644
index 000000000..ec6810e6c
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/SpecialityService.java
@@ -0,0 +1,46 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.SpecialtyDTO;
+import org.springframework.samples.petclinic.vet.Specialty;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("SpecialityService")
+public class SpecialityService implements BaseService {
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ @Override
+ public Specialty dtoToEntity(SpecialtyDTO dto) {
+ return modelMapper.map(dto, Specialty.class);
+ }
+
+ @Override
+ public SpecialtyDTO entityToDTO(Specialty entity) {
+ return modelMapper.map(entity, SpecialtyDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(Specialty entity:entities) {
+ dtos.add(entityToDTO(entity));
+ }
+
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(SpecialtyDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/VetService.java b/src/main/java/org/springframework/samples/petclinic/service/VetService.java
new file mode 100644
index 000000000..75dcf53ba
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/VetService.java
@@ -0,0 +1,60 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.VetDTO;
+import org.springframework.samples.petclinic.repository.VetRepository;
+import org.springframework.samples.petclinic.vet.Vet;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("VetService")
+public class VetService implements BaseService{
+
+ private final VetRepository vetRepository;
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ public VetService(VetRepository vetRepository) {
+ this.vetRepository = vetRepository;
+ }
+
+ @Override
+ public Vet dtoToEntity(VetDTO dto) {
+ return modelMapper.map(dto, Vet.class);
+ }
+
+ @Override
+ public VetDTO entityToDTO(Vet entity) {
+ return modelMapper.map(entity, VetDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(Vet entity: entities) {
+ dtos.add(entityToDTO(entity));
+ }
+
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(VetDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+
+
+ public Collection findAll() {
+ Collection vets = vetRepository.findAll();
+ return entitiesToDTOS(vets);
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/service/VisitService.java b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java
new file mode 100644
index 000000000..f2e173a52
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/service/VisitService.java
@@ -0,0 +1,68 @@
+package org.springframework.samples.petclinic.service;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.samples.petclinic.dto.VisitDTO;
+import org.springframework.samples.petclinic.visit.Visit;
+import org.springframework.samples.petclinic.repository.VisitRepository;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+@Service("VisitService")
+public class VisitService implements BaseService{
+
+ private final VisitRepository visitRepository;
+ private final ModelMapper modelMapper = new ModelMapper();
+
+ public VisitService(VisitRepository visitRepository) {
+ this.visitRepository = visitRepository;
+ }
+
+ @Override
+ public Visit dtoToEntity(VisitDTO dto) {
+ return modelMapper.map(dto, Visit.class);
+ }
+
+ @Override
+ public VisitDTO entityToDTO(Visit entity) {
+ return modelMapper.map(entity, VisitDTO.class);
+ }
+
+ @Override
+ public Collection entitiesToDTOS(Collection entities) {
+ Collection dtos = new HashSet<>();
+
+ for(Visit entity: entities) {
+ dtos.add(entityToDTO(entity));
+ }
+ return dtos;
+ }
+
+ @Override
+ public Collection dtosToEntities(Collection dtos) {
+ Collection entities = new HashSet<>();
+
+ for(VisitDTO dto: dtos) {
+ entities.add(dtoToEntity(dto));
+ }
+
+ return entities;
+ }
+
+ public void save(VisitDTO visitDTO) {
+ Visit visit = dtoToEntity(visitDTO);
+ visitRepository.save(visit);
+ }
+
+ public Collection findByPetId(Integer petId) {
+ Collection visits = visitRepository.findByPetId(petId);
+ Collection visitDTOS = new HashSet<>();
+
+ for (Visit visit: visits) {
+ visitDTOS.add(entityToDTO(visit));
+ }
+
+ return visitDTOS;
+ }
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java
index 226db01fe..90736badb 100644
--- a/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/PetclinicIntegrationTests.java
@@ -19,7 +19,7 @@ package org.springframework.samples.petclinic;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.samples.petclinic.vet.VetRepository;
+import org.springframework.samples.petclinic.repository.VetRepository;
@SpringBootTest
class PetclinicIntegrationTests {
diff --git a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java
index 1d6249c5d..a41e16fc3 100644
--- a/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/owner/OwnerControllerTests.java
@@ -28,8 +28,10 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.samples.petclinic.controller.OwnerController;
+import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.visit.Visit;
-import org.springframework.samples.petclinic.visit.VisitRepository;
+import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.empty;
diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java
index 47c444a78..2523e6101 100755
--- a/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/owner/PetControllerTests.java
@@ -31,6 +31,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
+import org.springframework.samples.petclinic.controller.PetController;
+import org.springframework.samples.petclinic.repository.OwnerRepository;
+import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.test.web.servlet.MockMvc;
/**
diff --git a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java
index adb96b69d..44c051119 100644
--- a/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/owner/PetTypeFormatterTests.java
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.samples.petclinic.repository.PetRepository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
diff --git a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java
index 84bee72df..86355cb4f 100644
--- a/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/owner/VisitControllerTests.java
@@ -28,7 +28,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.samples.petclinic.visit.VisitRepository;
+import org.springframework.samples.petclinic.controller.VisitController;
+import org.springframework.samples.petclinic.repository.PetRepository;
+import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.test.web.servlet.MockMvc;
/**
diff --git a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java
index a7f3d9d24..a5849fb44 100644
--- a/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/service/ClinicServiceTests.java
@@ -26,14 +26,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.samples.petclinic.owner.Owner;
-import org.springframework.samples.petclinic.owner.OwnerRepository;
+import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.owner.Pet;
-import org.springframework.samples.petclinic.owner.PetRepository;
+import org.springframework.samples.petclinic.repository.PetRepository;
import org.springframework.samples.petclinic.owner.PetType;
import org.springframework.samples.petclinic.vet.Vet;
-import org.springframework.samples.petclinic.vet.VetRepository;
+import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.samples.petclinic.visit.Visit;
-import org.springframework.samples.petclinic.visit.VisitRepository;
+import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
diff --git a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java
index fd537bee2..1488ff611 100644
--- a/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java
+++ b/src/test/java/org/springframework/samples/petclinic/vet/VetControllerTests.java
@@ -31,6 +31,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
+import org.springframework.samples.petclinic.controller.VetController;
+import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;