From 64c11838920ef126cf4ed91d0d4dc04184292536 Mon Sep 17 00:00:00 2001 From: Josue Page Date: Tue, 7 Sep 2021 10:13:07 +0200 Subject: [PATCH] Refactoring and documentation of ImportCSV.java ready --- .../petclinic/rest/importcsv/ImportCSV.java | 262 ++++++++++++------ 1 file changed, 173 insertions(+), 89 deletions(-) diff --git a/src/main/java/org/springframework/samples/petclinic/rest/importcsv/ImportCSV.java b/src/main/java/org/springframework/samples/petclinic/rest/importcsv/ImportCSV.java index 4e174f4..7330e94 100644 --- a/src/main/java/org/springframework/samples/petclinic/rest/importcsv/ImportCSV.java +++ b/src/main/java/org/springframework/samples/petclinic/rest/importcsv/ImportCSV.java @@ -13,10 +13,10 @@ import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; @RestController @CrossOrigin(exposedHeaders = "errors, content-type") @@ -26,114 +26,198 @@ public class ImportCSV { @Autowired private ClinicService clinicService; + + /** importPets: Parses a csv message and adds/deletes pets from the clinicService + * @param csv + * @return ResponseEntity> + */ @PreAuthorize("hasRole(@roles.OWNER_ADMIN)") @RequestMapping(value = "importPets", method = RequestMethod.POST, consumes = "text/plain", produces = "application/json") public ResponseEntity> importPets(@RequestBody String csv) { - - int i = 0; - List pets = new LinkedList(); - Pet pet; - - do { - pet = new Pet(); - - String field = ""; - while (i < csv.length() && csv.charAt(i) != ';') { - field += csv.charAt(i++); + // the method has to renamed - it doesn't just import, it also deletes + List petsToAdd = new LinkedList<>(); + List petsToDelete = new LinkedList<>(); + for (String line : csv.split("\\r?\\n")) { + String[] fields = line.split(";"); + + if (fields.length < 5) { + return errorResponse("not enough values"); } - i++; - pet.setName(field); + Pet pet = new Pet(); + pet.setName(fields[0]); + SettingResponse settingResponse; - field = ""; - while (i < csv.length() && csv.charAt(i) != ';') { - field += csv.charAt(i++); - } - i++; - - try { - pet.setBirthDate((new SimpleDateFormat("yyyy-MM-dd")).parse(field)); - } catch (ParseException e) { - HttpHeaders headers = new HttpHeaders(); - headers.add("errors", "date " + field + " not valid"); - return new ResponseEntity>(headers, HttpStatus.BAD_REQUEST); + settingResponse = setDateOfBirth(pet, fields[1]); + if (!settingResponse.isSuccessful) { + return errorResponse(settingResponse.errorMessage); } - field = ""; - while (i < csv.length() && csv.charAt(i) != ';') { - field += csv.charAt(i++); - } - i++; - - if (pet != null) { - ArrayList ts = (ArrayList) clinicService.findPetTypes(); - for (int j = 0; j < ts.size(); j++) { - if (ts.get(j).getName().toLowerCase().equals(field)) { - pet.setType(ts.get(j)); - break; - } - } + settingResponse = setPetType(pet, fields[2]); + if (!settingResponse.isSuccessful) { + return errorResponse(settingResponse.errorMessage); } - field = ""; - while (i < csv.length() && (csv.charAt(i) != ';' && csv.charAt(i) != '\n')) { - field += csv.charAt(i++); + settingResponse = setOwner(pet, fields[3]); + if (!settingResponse.isSuccessful) { + return errorResponse(settingResponse.errorMessage); } - if (pet != null) { - String owner = field; - List matchingOwners = clinicService.findAllOwners() - .stream() - .filter(o -> o.getLastName().equals(owner)) - .collect(Collectors.toList()); - - if (matchingOwners.size() == 0) { - HttpHeaders headers = new HttpHeaders(); - headers.add("errors", "Owner not found"); - return new ResponseEntity>(headers, HttpStatus.BAD_REQUEST); - } - if (matchingOwners.size() > 1) { - HttpHeaders headers = new HttpHeaders(); - headers.add("errors", "Owner not unique"); - return new ResponseEntity>(headers, HttpStatus.BAD_REQUEST); - } - pet.setOwner(matchingOwners.iterator().next()); + String action = fields[4]; + if (action.equalsIgnoreCase("add")) { + petsToAdd.add(pet); + } else if (action.equalsIgnoreCase("delete")) { + petsToDelete.add(pet); + } else { + return errorResponse("invalid action"); } + } + + for (Pet p : petsToAdd) { + clinicService.savePet(p); + } + + for (Pet p : petsToDelete) { + deletePet(p); + } + + return new ResponseEntity<>( + Stream.concat( + petsToAdd.stream(), + petsToDelete.stream() + ).collect(Collectors.toList()), + HttpStatus.OK + ); + } - if (csv.charAt(i) == ';') { - i++; - - field = ""; - while (i < csv.length() && csv.charAt(i) != '\n') { - field += csv.charAt(i++); - } - - if (field.toLowerCase().equals("add")) { - clinicService.savePet(pet); - } else { - for (Pet q : pet.getOwner().getPets()) { - if (q.getName().equals(pet.getName())) { - if (q.getType().getId().equals(pet.getType().getId())) { - if (pet.getBirthDate().equals(q.getBirthDate())) { - clinicService.deletePet(q); - } - } - } - } - } + private static class SettingResponse { + public boolean isSuccessful; + public String errorMessage; - } else { - clinicService.savePet(pet); - } - i++; + public SettingResponse() { + this.isSuccessful = true; + this.errorMessage = null; + } + + public SettingResponse(String errorMessage) { + this.isSuccessful = false; + this.errorMessage = errorMessage; + } + } + + + /** errorResponse: Creates an Http message with a bad request and a user defined message (headerValue). + * @param headerValue + * @return ResponseEntity> + */ + private ResponseEntity> errorResponse(String headerValue) { + HttpHeaders headers = new HttpHeaders(); + headers.add("errors", headerValue); + return new ResponseEntity<>(headers, HttpStatus.BAD_REQUEST); + } + + + /** setDateOfBirth: Set's birthday to a pet, by parsing a string into a date. + * @param pet + * @param dateOfBirth + * @return SettingResponse + */ + private SettingResponse setDateOfBirth(Pet pet, String dateOfBirth) { + try { + pet.setBirthDate((new SimpleDateFormat("yyyy-MM-dd")).parse(dateOfBirth)); + return new SettingResponse(); + } catch (ParseException e) { + return new SettingResponse("date " + dateOfBirth + " not valid"); + } + } + + + /** setPetType: Assigns a pet type to a pet. + * @param pet + * @param petTypeName + * @return SettingResponse + */ + private SettingResponse setPetType(Pet pet, String petTypeName) { + PetType petType = findPetTypeByName(petTypeName); + if (petType != null) { + pet.setType(petType); + return new SettingResponse(); + } + return new SettingResponse("type " + petTypeName + " not valid"); + } + + + /** setOwner: Sets an owner to a pet, returns errors if not found. + * @param pet + * @param ownerName + * @return SettingResponse + */ + private SettingResponse setOwner(Pet pet, String ownerName) { + List matchingOwners = findOwnersByName(ownerName); + if (matchingOwners.size() == 1) { + pet.setOwner(matchingOwners.iterator().next()); + return new SettingResponse(); + } else if (matchingOwners.size() > 1) { + return new SettingResponse("Owner not unique"); + } else { + return new SettingResponse("Owner not found"); + } + } + + + /** findPetTypeByName: Finds a pet in the clinicService, and returns null if not found. + * @param name + * @return PetType + */ + private PetType findPetTypeByName(String name) { + return clinicService.findPetTypes().stream().filter( + petType -> name.equals(petType.getName().toLowerCase()) + ).findFirst().orElse(null); + } - pets.add(pet); + + /** findOwnersByName: Finds a list of owners by it's name. + * @param name + * @return List + */ + private List findOwnersByName(String name) { + return clinicService.findAllOwners() + .stream() + .filter(o -> o.getLastName().equals(name)) + .collect(Collectors.toList()); + } - } while (i < csv.length() && pet != null); + + /** deletePet: Deletes a pet from the clinicService. + * @param pet + */ + private void deletePet(Pet pet) { + for (Pet existingPet : pet.getOwner().getPets()) { + if (equalPets(pet, existingPet)) { + clinicService.deletePet(existingPet); + } + } + } - return new ResponseEntity>(pets, HttpStatus.OK); + + /** equalPets: Compares if two pets are the same, by comparing name, type and birthdate. + * @param pet1 + * @param pet2 + * @return boolean + */ + private boolean equalPets(Pet pet1, Pet pet2) { + if (!pet1.getName().equals(pet2.getName())) { + return false; + } + if (!pet1.getType().getId().equals(pet2.getType().getId())) { + return false; + } + if (!pet1.getBirthDate().equals(pet2.getBirthDate())) { + return false; + } + return true; } }