mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-23 15:55:49 +00:00
Eliminadas clases a excepción de Owner y las básicas
This commit is contained in:
parent
e2fbc56130
commit
6fe1d6b1fb
28 changed files with 16 additions and 1718 deletions
14
pom.xml
14
pom.xml
|
@ -123,19 +123,7 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>io.spring.javaformat</groupId>
|
|
||||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
|
||||||
<version>${spring-format.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>validate</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
|
|
@ -59,8 +59,6 @@ public class Owner extends Person {
|
||||||
@Digits(fraction = 0, integer = 10)
|
@Digits(fraction = 0, integer = 10)
|
||||||
private String telephone;
|
private String telephone;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
|
|
||||||
private Set<Pet> pets;
|
|
||||||
|
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return this.address;
|
return this.address;
|
||||||
|
@ -86,57 +84,7 @@ public class Owner extends Person {
|
||||||
this.telephone = telephone;
|
this.telephone = telephone;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<Pet> getPetsInternal() {
|
|
||||||
if (this.pets == null) {
|
|
||||||
this.pets = new HashSet<>();
|
|
||||||
}
|
|
||||||
return this.pets;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setPetsInternal(Set<Pet> pets) {
|
|
||||||
this.pets = pets;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pet> getPets() {
|
|
||||||
List<Pet> sortedPets = new ArrayList<>(getPetsInternal());
|
|
||||||
PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
|
|
||||||
return Collections.unmodifiableList(sortedPets);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPet(Pet pet) {
|
|
||||||
if (pet.isNew()) {
|
|
||||||
getPetsInternal().add(pet);
|
|
||||||
}
|
|
||||||
pet.setOwner(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the Pet with the given name, or null if none found for this Owner.
|
|
||||||
* @param name to test
|
|
||||||
* @return true if pet name is already in use
|
|
||||||
*/
|
|
||||||
public Pet getPet(String name) {
|
|
||||||
return getPet(name, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the Pet with the given name, or null if none found for this Owner.
|
|
||||||
* @param name to test
|
|
||||||
* @return true if pet name is already in use
|
|
||||||
*/
|
|
||||||
public Pet getPet(String name, boolean ignoreNew) {
|
|
||||||
name = name.toLowerCase();
|
|
||||||
for (Pet pet : getPetsInternal()) {
|
|
||||||
if (!ignoreNew || !pet.isNew()) {
|
|
||||||
String compName = pet.getName();
|
|
||||||
compName = compName.toLowerCase();
|
|
||||||
if (compName.equals(name)) {
|
|
||||||
return pet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.samples.petclinic.owner;
|
package org.springframework.samples.petclinic.owner;
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
|
@ -43,11 +42,11 @@ class OwnerController {
|
||||||
|
|
||||||
private final OwnerRepository owners;
|
private final OwnerRepository owners;
|
||||||
|
|
||||||
private VisitRepository visits;
|
|
||||||
|
|
||||||
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
|
|
||||||
|
public OwnerController(OwnerRepository clinicService) {
|
||||||
this.owners = clinicService;
|
this.owners = clinicService;
|
||||||
this.visits = visits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@InitBinder
|
@InitBinder
|
||||||
|
@ -125,21 +124,14 @@ class OwnerController {
|
||||||
return "redirect:/owners/{ownerId}";
|
return "redirect:/owners/{ownerId}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom handler for displaying an owner.
|
|
||||||
* @param ownerId the ID of the owner to display
|
|
||||||
* @return a ModelMap with the model attributes for the view
|
|
||||||
*/
|
|
||||||
@GetMapping("/owners/{ownerId}")
|
@GetMapping("/owners/{ownerId}")
|
||||||
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
|
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
|
||||||
ModelAndView mav = new ModelAndView("owners/ownerDetails");
|
ModelAndView mav = new ModelAndView("owners/ownerDetails");
|
||||||
Owner owner = this.owners.findById(ownerId);
|
Owner owner = this.owners.findById(ownerId);
|
||||||
for (Pet pet : owner.getPets()) {
|
|
||||||
pet.setVisitsInternal(visits.findByPetId(pet.getId()));
|
|
||||||
}
|
|
||||||
mav.addObject(owner);
|
mav.addObject(owner);
|
||||||
return mav;
|
return mav;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
|
||||||
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
|
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
|
||||||
* found)
|
* found)
|
||||||
*/
|
*/
|
||||||
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
|
@Query("SELECT DISTINCT owner FROM Owner owner WHERE owner.lastName LIKE :lastName%")
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
Collection<Owner> findByLastName(@Param("lastName") String lastName);
|
Collection<Owner> findByLastName(@Param("lastName") String lastName);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
|
||||||
* @param id the id to search for
|
* @param id the id to search for
|
||||||
* @return the {@link Owner} if found
|
* @return the {@link Owner} if found
|
||||||
*/
|
*/
|
||||||
@Query("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id")
|
@Query("SELECT owner FROM Owner owner WHERE id =:id")
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
Owner findById(@Param("id") Integer id);
|
Owner findById(@Param("id") Integer id);
|
||||||
|
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.persistence.Transient;
|
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
|
||||||
import org.springframework.samples.petclinic.visit.Visit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple business object representing a pet.
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "pets")
|
|
||||||
public class Pet extends NamedEntity {
|
|
||||||
|
|
||||||
@Column(name = "birth_date")
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
|
||||||
private LocalDate birthDate;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
@JoinColumn(name = "type_id")
|
|
||||||
private PetType type;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
@JoinColumn(name = "owner_id")
|
|
||||||
private Owner owner;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private Set<Visit> 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 Owner getOwner() {
|
|
||||||
return this.owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setOwner(Owner owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Set<Visit> getVisitsInternal() {
|
|
||||||
if (this.visits == null) {
|
|
||||||
this.visits = new HashSet<>();
|
|
||||||
}
|
|
||||||
return this.visits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setVisitsInternal(Collection<Visit> visits) {
|
|
||||||
this.visits = new LinkedHashSet<>(visits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Visit> getVisits() {
|
|
||||||
List<Visit> sortedVisits = new ArrayList<>(getVisitsInternal());
|
|
||||||
PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
|
|
||||||
return Collections.unmodifiableList(sortedVisits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addVisit(Visit visit) {
|
|
||||||
getVisitsInternal().add(visit);
|
|
||||||
visit.setPetId(this.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/owners/{ownerId}")
|
|
||||||
class PetController {
|
|
||||||
|
|
||||||
private static final String VIEWS_PETS_CREATE_OR_UPDATE_FORM = "pets/createOrUpdatePetForm";
|
|
||||||
|
|
||||||
private final PetRepository pets;
|
|
||||||
|
|
||||||
private final OwnerRepository owners;
|
|
||||||
|
|
||||||
public PetController(PetRepository pets, OwnerRepository owners) {
|
|
||||||
this.pets = pets;
|
|
||||||
this.owners = owners;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("types")
|
|
||||||
public Collection<PetType> populatePetTypes() {
|
|
||||||
return this.pets.findPetTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModelAttribute("owner")
|
|
||||||
public Owner findOwner(@PathVariable("ownerId") int ownerId) {
|
|
||||||
return this.owners.findById(ownerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@InitBinder("owner")
|
|
||||||
public void initOwnerBinder(WebDataBinder dataBinder) {
|
|
||||||
dataBinder.setDisallowedFields("id");
|
|
||||||
}
|
|
||||||
|
|
||||||
@InitBinder("pet")
|
|
||||||
public void initPetBinder(WebDataBinder dataBinder) {
|
|
||||||
dataBinder.setValidator(new PetValidator());
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/pets/new")
|
|
||||||
public String initCreationForm(Owner owner, ModelMap model) {
|
|
||||||
Pet pet = new Pet();
|
|
||||||
owner.addPet(pet);
|
|
||||||
model.put("pet", pet);
|
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/pets/new")
|
|
||||||
public String processCreationForm(Owner owner, @Valid Pet pet, BindingResult result, ModelMap model) {
|
|
||||||
if (StringUtils.hasLength(pet.getName()) && pet.isNew() && owner.getPet(pet.getName(), true) != null) {
|
|
||||||
result.rejectValue("name", "duplicate", "already exists");
|
|
||||||
}
|
|
||||||
owner.addPet(pet);
|
|
||||||
if (result.hasErrors()) {
|
|
||||||
model.put("pet", pet);
|
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.pets.save(pet);
|
|
||||||
return "redirect:/owners/{ownerId}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/pets/{petId}/edit")
|
|
||||||
public String initUpdateForm(@PathVariable("petId") int petId, ModelMap model) {
|
|
||||||
Pet pet = this.pets.findById(petId);
|
|
||||||
model.put("pet", pet);
|
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/pets/{petId}/edit")
|
|
||||||
public String processUpdateForm(@Valid Pet pet, BindingResult result, Owner owner, ModelMap model) {
|
|
||||||
if (result.hasErrors()) {
|
|
||||||
pet.setOwner(owner);
|
|
||||||
model.put("pet", pet);
|
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
owner.addPet(pet);
|
|
||||||
this.pets.save(pet);
|
|
||||||
return "redirect:/owners/{ownerId}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.List;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository class for <code>Pet</code> domain objects All method names are compliant
|
|
||||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
|
||||||
* Data. See:
|
|
||||||
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
* @author Michael Isvy
|
|
||||||
*/
|
|
||||||
public interface PetRepository extends Repository<Pet, Integer> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve all {@link PetType}s from the data store.
|
|
||||||
* @return a Collection of {@link PetType}s.
|
|
||||||
*/
|
|
||||||
@Query("SELECT ptype FROM PetType ptype ORDER BY ptype.name")
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
List<PetType> findPetTypes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a {@link Pet} from the data store by id.
|
|
||||||
* @param id the id to search for
|
|
||||||
* @return the {@link Pet} if found
|
|
||||||
*/
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
Pet findById(Integer id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save a {@link Pet} to the data store, either inserting or updating it.
|
|
||||||
* @param pet the {@link Pet} to save
|
|
||||||
*/
|
|
||||||
void save(Pet pet);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 javax.persistence.Entity;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "types")
|
|
||||||
public class PetType extends NamedEntity {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.text.ParseException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.format.Formatter;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting
|
|
||||||
* from Spring 3.0, Formatters have come as an improvement in comparison to legacy
|
|
||||||
* PropertyEditors. See the following links for more details: - The Spring ref doc:
|
|
||||||
* https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#format
|
|
||||||
*
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Michael Isvy
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class PetTypeFormatter implements Formatter<PetType> {
|
|
||||||
|
|
||||||
private final PetRepository pets;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public PetTypeFormatter(PetRepository pets) {
|
|
||||||
this.pets = pets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String print(PetType petType, Locale locale) {
|
|
||||||
return petType.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PetType parse(String text, Locale locale) throws ParseException {
|
|
||||||
Collection<PetType> findPetTypes = this.pets.findPetTypes();
|
|
||||||
for (PetType type : findPetTypes) {
|
|
||||||
if (type.getName().equals(text)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new ParseException("type not found: " + text, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.validation.Errors;
|
|
||||||
import org.springframework.validation.Validator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>Validator</code> for <code>Pet</code> forms.
|
|
||||||
* <p>
|
|
||||||
* We're not using Bean Validation annotations here because it is easier to define such
|
|
||||||
* validation rule in Java.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
*/
|
|
||||||
public class PetValidator implements Validator {
|
|
||||||
|
|
||||||
private static final String REQUIRED = "required";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validate(Object obj, Errors errors) {
|
|
||||||
Pet pet = (Pet) obj;
|
|
||||||
String name = pet.getName();
|
|
||||||
// name validation
|
|
||||||
if (!StringUtils.hasLength(name)) {
|
|
||||||
errors.rejectValue("name", REQUIRED, REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// type validation
|
|
||||||
if (pet.isNew() && pet.getType() == null) {
|
|
||||||
errors.rejectValue("type", REQUIRED, REQUIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// birth date validation
|
|
||||||
if (pet.getBirthDate() == null) {
|
|
||||||
errors.rejectValue("birthDate", REQUIRED, REQUIRED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This Validator validates *just* Pet instances
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean supports(Class<?> clazz) {
|
|
||||||
return Pet.class.isAssignableFrom(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.Map;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.visit.Visit;
|
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @author Michael Isvy
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
class VisitController {
|
|
||||||
|
|
||||||
private final VisitRepository visits;
|
|
||||||
|
|
||||||
private final PetRepository pets;
|
|
||||||
|
|
||||||
public VisitController(VisitRepository visits, PetRepository pets) {
|
|
||||||
this.visits = visits;
|
|
||||||
this.pets = pets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@InitBinder
|
|
||||||
public void setAllowedFields(WebDataBinder dataBinder) {
|
|
||||||
dataBinder.setDisallowedFields("id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called before each and every @RequestMapping annotated method. 2 goals: - Make sure
|
|
||||||
* we always have fresh data - Since we do not use the session scope, make sure that
|
|
||||||
* Pet object always has an id (Even though id is not part of the form fields)
|
|
||||||
* @param petId
|
|
||||||
* @return Pet
|
|
||||||
*/
|
|
||||||
@ModelAttribute("visit")
|
|
||||||
public Visit loadPetWithVisit(@PathVariable("petId") int petId, Map<String, Object> model) {
|
|
||||||
Pet pet = this.pets.findById(petId);
|
|
||||||
pet.setVisitsInternal(this.visits.findByPetId(petId));
|
|
||||||
model.put("pet", pet);
|
|
||||||
Visit visit = new Visit();
|
|
||||||
pet.addVisit(visit);
|
|
||||||
return visit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spring MVC calls method loadPetWithVisit(...) before initNewVisitForm is called
|
|
||||||
@GetMapping("/owners/*/pets/{petId}/visits/new")
|
|
||||||
public String initNewVisitForm(@PathVariable("petId") int petId, Map<String, Object> model) {
|
|
||||||
return "pets/createOrUpdateVisitForm";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spring MVC calls method loadPetWithVisit(...) before processNewVisitForm is called
|
|
||||||
@PostMapping("/owners/{ownerId}/pets/{petId}/visits/new")
|
|
||||||
public String processNewVisitForm(@Valid Visit visit, BindingResult result) {
|
|
||||||
if (result.hasErrors()) {
|
|
||||||
return "pets/createOrUpdateVisitForm";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.visits.save(visit);
|
|
||||||
return "redirect:/owners/{ownerId}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.springframework.samples.petclinic.model.NamedEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Models a {@link Vet Vet's} specialty (for example, dentistry).
|
|
||||||
*
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "specialties")
|
|
||||||
public class Specialty extends NamedEntity implements Serializable {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.JoinTable;
|
|
||||||
import javax.persistence.ManyToMany;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
|
||||||
import org.springframework.samples.petclinic.model.Person;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple JavaBean domain object representing a veterinarian.
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "vets")
|
|
||||||
public class Vet extends Person {
|
|
||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER)
|
|
||||||
@JoinTable(name = "vet_specialties", joinColumns = @JoinColumn(name = "vet_id"),
|
|
||||||
inverseJoinColumns = @JoinColumn(name = "specialty_id"))
|
|
||||||
private Set<Specialty> specialties;
|
|
||||||
|
|
||||||
protected Set<Specialty> getSpecialtiesInternal() {
|
|
||||||
if (this.specialties == null) {
|
|
||||||
this.specialties = new HashSet<>();
|
|
||||||
}
|
|
||||||
return this.specialties;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSpecialtiesInternal(Set<Specialty> specialties) {
|
|
||||||
this.specialties = specialties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlElement
|
|
||||||
public List<Specialty> getSpecialties() {
|
|
||||||
List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
|
|
||||||
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
|
|
||||||
return Collections.unmodifiableList(sortedSpecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNrOfSpecialties() {
|
|
||||||
return getSpecialtiesInternal().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSpecialty(Specialty specialty) {
|
|
||||||
getSpecialtiesInternal().add(specialty);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
class VetController {
|
|
||||||
|
|
||||||
private final VetRepository vets;
|
|
||||||
|
|
||||||
public VetController(VetRepository clinicService) {
|
|
||||||
this.vets = clinicService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/vets.html")
|
|
||||||
public String showVetList(Map<String, Object> 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());
|
|
||||||
model.put("vets", vets);
|
|
||||||
return "vets/vetList";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping({ "/vets" })
|
|
||||||
public @ResponseBody Vets 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());
|
|
||||||
return vets;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository class for <code>Vet</code> domain objects All method names are compliant
|
|
||||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
|
||||||
* Data. See:
|
|
||||||
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
* @author Michael Isvy
|
|
||||||
*/
|
|
||||||
public interface VetRepository extends Repository<Vet, Integer> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve all <code>Vet</code>s from the data store.
|
|
||||||
* @return a <code>Collection</code> of <code>Vet</code>s
|
|
||||||
*/
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
@Cacheable("vets")
|
|
||||||
Collection<Vet> findAll() throws DataAccessException;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple domain object representing a list of veterinarians. Mostly here to be used for
|
|
||||||
* the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}.
|
|
||||||
*
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
@XmlRootElement
|
|
||||||
public class Vets {
|
|
||||||
|
|
||||||
private List<Vet> vets;
|
|
||||||
|
|
||||||
@XmlElement
|
|
||||||
public List<Vet> getVetList() {
|
|
||||||
if (vets == null) {
|
|
||||||
vets = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return vets;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.visit;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple JavaBean domain object representing a visit.
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
@Entity
|
|
||||||
@Table(name = "visits")
|
|
||||||
public class Visit extends BaseEntity {
|
|
||||||
|
|
||||||
@Column(name = "visit_date")
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
|
||||||
private LocalDate date;
|
|
||||||
|
|
||||||
@NotEmpty
|
|
||||||
@Column(name = "description")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@Column(name = "pet_id")
|
|
||||||
private Integer petId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of Visit for the current date
|
|
||||||
*/
|
|
||||||
public Visit() {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.visit;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.data.repository.Repository;
|
|
||||||
import org.springframework.samples.petclinic.model.BaseEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository class for <code>Visit</code> domain objects All method names are compliant
|
|
||||||
* with Spring Data naming conventions so this interface can easily be extended for Spring
|
|
||||||
* Data. See:
|
|
||||||
* https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
* @author Michael Isvy
|
|
||||||
*/
|
|
||||||
public interface VisitRepository extends Repository<Visit, Integer> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save a <code>Visit</code> to the data store, either inserting or updating it.
|
|
||||||
* @param visit the <code>Visit</code> to save
|
|
||||||
* @see BaseEntity#isNew
|
|
||||||
*/
|
|
||||||
void save(Visit visit) throws DataAccessException;
|
|
||||||
|
|
||||||
List<Visit> findByPetId(Integer petId);
|
|
||||||
|
|
||||||
}
|
|
|
@ -30,53 +30,13 @@
|
||||||
|
|
||||||
<a th:href="@{{id}/edit(id=${owner.id})}" class="btn btn-default">Edit
|
<a th:href="@{{id}/edit(id=${owner.id})}" class="btn btn-default">Edit
|
||||||
Owner</a>
|
Owner</a>
|
||||||
<a th:href="@{{id}/pets/new(id=${owner.id})}" class="btn btn-default">Add
|
|
||||||
New Pet</a>
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<h2>Pets and Visits</h2>
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
|
||||||
|
|
||||||
<tr th:each="pet : ${owner.pets}">
|
|
||||||
<td valign="top">
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
<dt>Name</dt>
|
|
||||||
<dd th:text="${pet.name}"></dd>
|
|
||||||
<dt>Birth Date</dt>
|
|
||||||
<dd
|
|
||||||
th:text="${#temporals.format(pet.birthDate, 'yyyy-MM-dd')}"></dd>
|
|
||||||
<dt>Type</dt>
|
|
||||||
<dd th:text="${pet.type}"></dd>
|
|
||||||
</dl>
|
|
||||||
</td>
|
|
||||||
<td valign="top">
|
|
||||||
<table class="table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Visit Date</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr th:each="visit : ${pet.visits}">
|
|
||||||
<td th:text="${#temporals.format(visit.date, 'yyyy-MM-dd')}"></td>
|
|
||||||
<td th:text="${visit?.description}"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><a
|
|
||||||
th:href="@{{ownerId}/pets/{petId}/edit(ownerId=${owner.id},petId=${pet.id})}">Edit
|
|
||||||
Pet</a></td>
|
|
||||||
<td><a
|
|
||||||
th:href="@{{ownerId}/pets/{petId}/visits/new(ownerId=${owner.id},petId=${pet.id})}">Add
|
|
||||||
Visit</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
<td th:text="${owner.address}"/>
|
<td th:text="${owner.address}"/>
|
||||||
<td th:text="${owner.city}"/>
|
<td th:text="${owner.city}"/>
|
||||||
<td th:text="${owner.telephone}"/>
|
<td th:text="${owner.telephone}"/>
|
||||||
<td><span th:each="pet : ${owner.pets}" th:text="${pet.name} "/></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -19,18 +19,10 @@ package org.springframework.samples.petclinic;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.samples.petclinic.vet.VetRepository;
|
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class PetclinicIntegrationTests {
|
class PetclinicIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private VetRepository vets;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFindAll() throws Exception {
|
|
||||||
vets.findAll();
|
|
||||||
vets.findAll(); // served from cache
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.samples.petclinic.visit.Visit;
|
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
|
@ -59,8 +57,6 @@ class OwnerControllerTests {
|
||||||
@MockBean
|
@MockBean
|
||||||
private OwnerRepository owners;
|
private OwnerRepository owners;
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private VisitRepository visits;
|
|
||||||
|
|
||||||
private Owner george;
|
private Owner george;
|
||||||
|
|
||||||
|
@ -73,18 +69,10 @@ class OwnerControllerTests {
|
||||||
george.setAddress("110 W. Liberty St.");
|
george.setAddress("110 W. Liberty St.");
|
||||||
george.setCity("Madison");
|
george.setCity("Madison");
|
||||||
george.setTelephone("6085551023");
|
george.setTelephone("6085551023");
|
||||||
Pet max = new Pet();
|
|
||||||
PetType dog = new PetType();
|
|
||||||
dog.setName("dog");
|
|
||||||
max.setId(1);
|
|
||||||
max.setType(dog);
|
|
||||||
max.setName("Max");
|
|
||||||
max.setBirthDate(LocalDate.now());
|
|
||||||
george.setPetsInternal(Collections.singleton(max));
|
|
||||||
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
|
given(this.owners.findById(TEST_OWNER_ID)).willReturn(george);
|
||||||
Visit visit = new Visit();
|
|
||||||
visit.setDate(LocalDate.now());
|
|
||||||
given(this.visits.findByPetId(max.getId())).willReturn(Collections.singletonList(visit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -175,25 +163,7 @@ class OwnerControllerTests {
|
||||||
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
|
||||||
.andExpect(model().attribute("owner", hasProperty("pets", not(empty()))))
|
.andExpect(view().name("owners/ownerDetails"));
|
||||||
.andExpect(model().attribute("owner", hasProperty("pets", new BaseMatcher<List<Pet>>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean matches(Object item) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Pet> pets = (List<Pet>) item;
|
|
||||||
Pet pet = pets.get(0);
|
|
||||||
if (pet.getVisits().isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void describeTo(Description description) {
|
|
||||||
description.appendText("Max did not have any visits");
|
|
||||||
}
|
|
||||||
}))).andExpect(view().name("owners/ownerDetails"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 static org.mockito.BDDMockito.given;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
|
||||||
|
|
||||||
import org.assertj.core.util.Lists;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
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.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.FilterType;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for the {@link PetController}
|
|
||||||
*
|
|
||||||
* @author Colin But
|
|
||||||
*/
|
|
||||||
@WebMvcTest(value = PetController.class,
|
|
||||||
includeFilters = @ComponentScan.Filter(value = PetTypeFormatter.class, type = FilterType.ASSIGNABLE_TYPE))
|
|
||||||
class PetControllerTests {
|
|
||||||
|
|
||||||
private static final int TEST_OWNER_ID = 1;
|
|
||||||
|
|
||||||
private static final int TEST_PET_ID = 1;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private PetRepository pets;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private OwnerRepository owners;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() {
|
|
||||||
PetType cat = new PetType();
|
|
||||||
cat.setId(3);
|
|
||||||
cat.setName("hamster");
|
|
||||||
given(this.pets.findPetTypes()).willReturn(Lists.newArrayList(cat));
|
|
||||||
given(this.owners.findById(TEST_OWNER_ID)).willReturn(new Owner());
|
|
||||||
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInitCreationForm() throws Exception {
|
|
||||||
mockMvc.perform(get("/owners/{ownerId}/pets/new", TEST_OWNER_ID)).andExpect(status().isOk())
|
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm")).andExpect(model().attributeExists("pet"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessCreationFormSuccess() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty")
|
|
||||||
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessCreationFormHasErrors() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/new", TEST_OWNER_ID).param("name", "Betty").param("birthDate",
|
|
||||||
"2015-02-12")).andExpect(model().attributeHasNoErrors("owner"))
|
|
||||||
.andExpect(model().attributeHasErrors("pet")).andExpect(model().attributeHasFieldErrors("pet", "type"))
|
|
||||||
.andExpect(model().attributeHasFieldErrorCode("pet", "type", "required")).andExpect(status().isOk())
|
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInitUpdateForm() throws Exception {
|
|
||||||
mockMvc.perform(get("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID))
|
|
||||||
.andExpect(status().isOk()).andExpect(model().attributeExists("pet"))
|
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessUpdateFormSuccess() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
|
||||||
.param("type", "hamster").param("birthDate", "2015-02-12")).andExpect(status().is3xxRedirection())
|
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessUpdateFormHasErrors() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/{ownerId}/pets/{petId}/edit", TEST_OWNER_ID, TEST_PET_ID).param("name", "Betty")
|
|
||||||
.param("birthDate", "2015/02/12")).andExpect(model().attributeHasNoErrors("owner"))
|
|
||||||
.andExpect(model().attributeHasErrors("pet")).andExpect(status().isOk())
|
|
||||||
.andExpect(view().name("pets/createOrUpdatePetForm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.text.ParseException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for {@link PetTypeFormatter}
|
|
||||||
*
|
|
||||||
* @author Colin But
|
|
||||||
*/
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class PetTypeFormatterTests {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PetRepository pets;
|
|
||||||
|
|
||||||
private PetTypeFormatter petTypeFormatter;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() {
|
|
||||||
this.petTypeFormatter = new PetTypeFormatter(pets);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testPrint() {
|
|
||||||
PetType petType = new PetType();
|
|
||||||
petType.setName("Hamster");
|
|
||||||
String petTypeName = this.petTypeFormatter.print(petType, Locale.ENGLISH);
|
|
||||||
assertThat(petTypeName).isEqualTo("Hamster");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldParse() throws ParseException {
|
|
||||||
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
|
||||||
PetType petType = petTypeFormatter.parse("Bird", Locale.ENGLISH);
|
|
||||||
assertThat(petType.getName()).isEqualTo("Bird");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldThrowParseException() throws ParseException {
|
|
||||||
given(this.pets.findPetTypes()).willReturn(makePetTypes());
|
|
||||||
Assertions.assertThrows(ParseException.class, () -> {
|
|
||||||
petTypeFormatter.parse("Fish", Locale.ENGLISH);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to produce some sample pet types just for test purpose
|
|
||||||
* @return {@link Collection} of {@link PetType}
|
|
||||||
*/
|
|
||||||
private List<PetType> makePetTypes() {
|
|
||||||
List<PetType> petTypes = new ArrayList<>();
|
|
||||||
petTypes.add(new PetType() {
|
|
||||||
{
|
|
||||||
setName("Dog");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
petTypes.add(new PetType() {
|
|
||||||
{
|
|
||||||
setName("Bird");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return petTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 static org.mockito.BDDMockito.given;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
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.test.web.servlet.MockMvc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for {@link VisitController}
|
|
||||||
*
|
|
||||||
* @author Colin But
|
|
||||||
*/
|
|
||||||
@WebMvcTest(VisitController.class)
|
|
||||||
class VisitControllerTests {
|
|
||||||
|
|
||||||
private static final int TEST_PET_ID = 1;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private VisitRepository visits;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private PetRepository pets;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void init() {
|
|
||||||
given(this.pets.findById(TEST_PET_ID)).willReturn(new Pet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInitNewVisitForm() throws Exception {
|
|
||||||
mockMvc.perform(get("/owners/*/pets/{petId}/visits/new", TEST_PET_ID)).andExpect(status().isOk())
|
|
||||||
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessNewVisitFormSuccess() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George")
|
|
||||||
.param("description", "Visit Description")).andExpect(status().is3xxRedirection())
|
|
||||||
.andExpect(view().name("redirect:/owners/{ownerId}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testProcessNewVisitFormHasErrors() throws Exception {
|
|
||||||
mockMvc.perform(post("/owners/*/pets/{petId}/visits/new", TEST_PET_ID).param("name", "George"))
|
|
||||||
.andExpect(model().attributeHasErrors("visit")).andExpect(status().isOk())
|
|
||||||
.andExpect(view().name("pets/createOrUpdateVisitForm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,227 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.service;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
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.owner.Pet;
|
|
||||||
import org.springframework.samples.petclinic.owner.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.visit.Visit;
|
|
||||||
import org.springframework.samples.petclinic.visit.VisitRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Integration test of the Service and the Repository layer.
|
|
||||||
* <p>
|
|
||||||
* ClinicServiceSpringDataJpaTests subclasses benefit from the following services provided
|
|
||||||
* by the Spring TestContext Framework:
|
|
||||||
* </p>
|
|
||||||
* <ul>
|
|
||||||
* <li><strong>Spring IoC container caching</strong> which spares us unnecessary set up
|
|
||||||
* time between test execution.</li>
|
|
||||||
* <li><strong>Dependency Injection</strong> of test fixture instances, meaning that we
|
|
||||||
* don't need to perform application context lookups. See the use of
|
|
||||||
* {@link Autowired @Autowired} on the <code>{@link
|
|
||||||
* ClinicServiceTests#clinicService clinicService}</code> instance variable, which uses
|
|
||||||
* autowiring <em>by type</em>.
|
|
||||||
* <li><strong>Transaction management</strong>, meaning each test method is executed in
|
|
||||||
* its own transaction, which is automatically rolled back by default. Thus, even if tests
|
|
||||||
* insert or otherwise change database state, there is no need for a teardown or cleanup
|
|
||||||
* script.
|
|
||||||
* <li>An {@link org.springframework.context.ApplicationContext ApplicationContext} is
|
|
||||||
* also inherited and can be used for explicit bean lookup if necessary.</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author Ken Krebs
|
|
||||||
* @author Rod Johnson
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @author Sam Brannen
|
|
||||||
* @author Michael Isvy
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
@DataJpaTest(includeFilters = @ComponentScan.Filter(Service.class))
|
|
||||||
class ClinicServiceTests {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected OwnerRepository owners;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected PetRepository pets;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected VisitRepository visits;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected VetRepository vets;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindOwnersByLastName() {
|
|
||||||
Collection<Owner> owners = this.owners.findByLastName("Davis");
|
|
||||||
assertThat(owners).hasSize(2);
|
|
||||||
|
|
||||||
owners = this.owners.findByLastName("Daviss");
|
|
||||||
assertThat(owners).isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindSingleOwnerWithPet() {
|
|
||||||
Owner owner = this.owners.findById(1);
|
|
||||||
assertThat(owner.getLastName()).startsWith("Franklin");
|
|
||||||
assertThat(owner.getPets()).hasSize(1);
|
|
||||||
assertThat(owner.getPets().get(0).getType()).isNotNull();
|
|
||||||
assertThat(owner.getPets().get(0).getType().getName()).isEqualTo("cat");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void shouldInsertOwner() {
|
|
||||||
Collection<Owner> owners = this.owners.findByLastName("Schultz");
|
|
||||||
int found = owners.size();
|
|
||||||
|
|
||||||
Owner owner = new Owner();
|
|
||||||
owner.setFirstName("Sam");
|
|
||||||
owner.setLastName("Schultz");
|
|
||||||
owner.setAddress("4, Evans Street");
|
|
||||||
owner.setCity("Wollongong");
|
|
||||||
owner.setTelephone("4444444444");
|
|
||||||
this.owners.save(owner);
|
|
||||||
assertThat(owner.getId().longValue()).isNotEqualTo(0);
|
|
||||||
|
|
||||||
owners = this.owners.findByLastName("Schultz");
|
|
||||||
assertThat(owners.size()).isEqualTo(found + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void shouldUpdateOwner() {
|
|
||||||
Owner owner = this.owners.findById(1);
|
|
||||||
String oldLastName = owner.getLastName();
|
|
||||||
String newLastName = oldLastName + "X";
|
|
||||||
|
|
||||||
owner.setLastName(newLastName);
|
|
||||||
this.owners.save(owner);
|
|
||||||
|
|
||||||
// retrieving new name from database
|
|
||||||
owner = this.owners.findById(1);
|
|
||||||
assertThat(owner.getLastName()).isEqualTo(newLastName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindPetWithCorrectId() {
|
|
||||||
Pet pet7 = this.pets.findById(7);
|
|
||||||
assertThat(pet7.getName()).startsWith("Samantha");
|
|
||||||
assertThat(pet7.getOwner().getFirstName()).isEqualTo("Jean");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindAllPetTypes() {
|
|
||||||
Collection<PetType> petTypes = this.pets.findPetTypes();
|
|
||||||
|
|
||||||
PetType petType1 = EntityUtils.getById(petTypes, PetType.class, 1);
|
|
||||||
assertThat(petType1.getName()).isEqualTo("cat");
|
|
||||||
PetType petType4 = EntityUtils.getById(petTypes, PetType.class, 4);
|
|
||||||
assertThat(petType4.getName()).isEqualTo("snake");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void shouldInsertPetIntoDatabaseAndGenerateId() {
|
|
||||||
Owner owner6 = this.owners.findById(6);
|
|
||||||
int found = owner6.getPets().size();
|
|
||||||
|
|
||||||
Pet pet = new Pet();
|
|
||||||
pet.setName("bowser");
|
|
||||||
Collection<PetType> types = this.pets.findPetTypes();
|
|
||||||
pet.setType(EntityUtils.getById(types, PetType.class, 2));
|
|
||||||
pet.setBirthDate(LocalDate.now());
|
|
||||||
owner6.addPet(pet);
|
|
||||||
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
|
||||||
|
|
||||||
this.pets.save(pet);
|
|
||||||
this.owners.save(owner6);
|
|
||||||
|
|
||||||
owner6 = this.owners.findById(6);
|
|
||||||
assertThat(owner6.getPets().size()).isEqualTo(found + 1);
|
|
||||||
// checks that id has been generated
|
|
||||||
assertThat(pet.getId()).isNotNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void shouldUpdatePetName() throws Exception {
|
|
||||||
Pet pet7 = this.pets.findById(7);
|
|
||||||
String oldName = pet7.getName();
|
|
||||||
|
|
||||||
String newName = oldName + "X";
|
|
||||||
pet7.setName(newName);
|
|
||||||
this.pets.save(pet7);
|
|
||||||
|
|
||||||
pet7 = this.pets.findById(7);
|
|
||||||
assertThat(pet7.getName()).isEqualTo(newName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindVets() {
|
|
||||||
Collection<Vet> vets = this.vets.findAll();
|
|
||||||
|
|
||||||
Vet vet = EntityUtils.getById(vets, Vet.class, 3);
|
|
||||||
assertThat(vet.getLastName()).isEqualTo("Douglas");
|
|
||||||
assertThat(vet.getNrOfSpecialties()).isEqualTo(2);
|
|
||||||
assertThat(vet.getSpecialties().get(0).getName()).isEqualTo("dentistry");
|
|
||||||
assertThat(vet.getSpecialties().get(1).getName()).isEqualTo("surgery");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void shouldAddNewVisitForPet() {
|
|
||||||
Pet pet7 = this.pets.findById(7);
|
|
||||||
int found = pet7.getVisits().size();
|
|
||||||
Visit visit = new Visit();
|
|
||||||
pet7.addVisit(visit);
|
|
||||||
visit.setDescription("test");
|
|
||||||
this.visits.save(visit);
|
|
||||||
this.pets.save(pet7);
|
|
||||||
|
|
||||||
pet7 = this.pets.findById(7);
|
|
||||||
assertThat(pet7.getVisits().size()).isEqualTo(found + 1);
|
|
||||||
assertThat(visit.getId()).isNotNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindVisitsByPetId() throws Exception {
|
|
||||||
Collection<Visit> visits = this.visits.findByPetId(7);
|
|
||||||
assertThat(visits).hasSize(2);
|
|
||||||
Visit[] visitArr = visits.toArray(new Visit[visits.size()]);
|
|
||||||
assertThat(visitArr[0].getDate()).isNotNull();
|
|
||||||
assertThat(visitArr[0].getPetId()).isEqualTo(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import static org.mockito.BDDMockito.given;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
|
|
||||||
|
|
||||||
import org.assertj.core.util.Lists;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
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.http.MediaType;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test class for the {@link VetController}
|
|
||||||
*/
|
|
||||||
@WebMvcTest(VetController.class)
|
|
||||||
class VetControllerTests {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
private VetRepository vets;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() {
|
|
||||||
Vet james = new Vet();
|
|
||||||
james.setFirstName("James");
|
|
||||||
james.setLastName("Carter");
|
|
||||||
james.setId(1);
|
|
||||||
Vet helen = new Vet();
|
|
||||||
helen.setFirstName("Helen");
|
|
||||||
helen.setLastName("Leary");
|
|
||||||
helen.setId(2);
|
|
||||||
Specialty radiology = new Specialty();
|
|
||||||
radiology.setId(1);
|
|
||||||
radiology.setName("radiology");
|
|
||||||
helen.addSpecialty(radiology);
|
|
||||||
given(this.vets.findAll()).willReturn(Lists.newArrayList(james, helen));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShowVetListHtml() throws Exception {
|
|
||||||
mockMvc.perform(get("/vets.html")).andExpect(status().isOk()).andExpect(model().attributeExists("vets"))
|
|
||||||
.andExpect(view().name("vets/vetList"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShowResourcesVetList() throws Exception {
|
|
||||||
ResultActions actions = mockMvc.perform(get("/vets").accept(MediaType.APPLICATION_JSON))
|
|
||||||
.andExpect(status().isOk());
|
|
||||||
actions.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andExpect(jsonPath("$.vetList[0].id").value(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.vet;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.util.SerializationUtils;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
class VetTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSerialization() {
|
|
||||||
Vet vet = new Vet();
|
|
||||||
vet.setFirstName("Zaphod");
|
|
||||||
vet.setLastName("Beeblebrox");
|
|
||||||
vet.setId(123);
|
|
||||||
Vet other = (Vet) SerializationUtils.deserialize(SerializationUtils.serialize(vet));
|
|
||||||
assertThat(other.getFirstName()).isEqualTo(vet.getFirstName());
|
|
||||||
assertThat(other.getLastName()).isEqualTo(vet.getLastName());
|
|
||||||
assertThat(other.getId()).isEqualTo(vet.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue