diff --git a/db.xml b/db.xml index d920776..229c77a 100644 --- a/db.xml +++ b/db.xml @@ -1 +1 @@ -341Product A1000-5001711875600.0000000001part11000KILOGRAMSJohn Doe1234GREEN55.5Home \ No newline at end of file +341ewreqr14321324321711875600.000000000123243214342CENTIMETERS32432432143214WHITE342.0423214342Hello1341713267558.81380880012312312321CENTIMETERS123431BLACK2321.043231 \ No newline at end of file diff --git a/src/main/java/me/zinch/commands/Add.java b/src/main/java/me/zinch/commands/Add.java index d639939..fece20f 100644 --- a/src/main/java/me/zinch/commands/Add.java +++ b/src/main/java/me/zinch/commands/Add.java @@ -2,6 +2,8 @@ package me.zinch.commands; import me.zinch.console.Console; import me.zinch.exceptions.CommandActionException; +import me.zinch.exceptions.ValidationException; +import me.zinch.validator.Validators; import me.zinch.wrapper.ProductCollection; import java.util.regex.Pattern; @@ -18,7 +20,12 @@ public class Add extends Command { @Override public String action(ProductCollection productCollection) throws CommandActionException { var productDTO = Console.readProductDTO(); - var product = productCollection.addProduct(productDTO); - return String.format("Продукт %s был добавлен под id %d", product.getName(), product.getId()); + try { + Validators.validateObject(productDTO).throwIfNotValid(); + var product = productCollection.addProduct(productDTO); + return String.format("Продукт %s был добавлен под id %d", product.getName(), product.getId()); + } catch (ValidationException e) { + throw new CommandActionException(e.getMessage()); + } } } diff --git a/src/main/java/me/zinch/commands/AddIfMax.java b/src/main/java/me/zinch/commands/AddIfMax.java index 788c98c..c9b6942 100644 --- a/src/main/java/me/zinch/commands/AddIfMax.java +++ b/src/main/java/me/zinch/commands/AddIfMax.java @@ -1,6 +1,9 @@ package me.zinch.commands; import me.zinch.console.Console; +import me.zinch.exceptions.CommandActionException; +import me.zinch.exceptions.ValidationException; +import me.zinch.validator.Validators; import me.zinch.wrapper.ProductCollection; import java.util.regex.Pattern; @@ -15,13 +18,17 @@ public class AddIfMax extends Command { } @Override - public String action(ProductCollection productCollection) { + public String action(ProductCollection productCollection) throws CommandActionException { var productDTO = Console.readProductDTO(); - var product = productCollection.addIfMaxPrice(productDTO); - if (product.isPresent()) { - return String.format("Продукт %s был добавлен под id %d", product.get().getName(), product.get().getId()); - } else { + try { + Validators.validateObject(productDTO).throwIfNotValid(); + if (productCollection.getMaxPrice() < productDTO.getPrice()) { + var product = productCollection.addProduct(productDTO); + return String.format("Продукт %s был добавлен под id %d", product.getName(), product.getId()); + } return "Продукт не подходит под условие"; + } catch (ValidationException e) { + throw new CommandActionException(e.getMessage()); } } } diff --git a/src/main/java/me/zinch/commands/AddIfMin.java b/src/main/java/me/zinch/commands/AddIfMin.java index 1c07bc3..2d7a9a1 100644 --- a/src/main/java/me/zinch/commands/AddIfMin.java +++ b/src/main/java/me/zinch/commands/AddIfMin.java @@ -1,6 +1,9 @@ package me.zinch.commands; import me.zinch.console.Console; +import me.zinch.exceptions.CommandActionException; +import me.zinch.exceptions.ValidationException; +import me.zinch.validator.Validators; import me.zinch.wrapper.ProductCollection; import java.util.regex.Pattern; @@ -17,11 +20,15 @@ public class AddIfMin extends Command { @Override public String action(ProductCollection productCollection) { var productDTO = Console.readProductDTO(); - var product = productCollection.addIfMinPrice(productDTO); - if (product.isPresent()) { - return String.format("Продукт %s был добавлен под id %d", product.get().getName(), product.get().getId()); - } else { + try { + Validators.validateObject(productDTO).throwIfNotValid(); + if (productCollection.getMinPrice() > productDTO.getPrice()) { + var product = productCollection.addProduct(productDTO); + return String.format("Продукт %s был добавлен под id %d", product.getName(), product.getId()); + } return "Продукт не подходит под условие"; + } catch (ValidationException e) { + throw new CommandActionException(e.getMessage()); } } } diff --git a/src/main/java/me/zinch/commands/Exit.java b/src/main/java/me/zinch/commands/Exit.java index 8d03e7d..679cf6a 100644 --- a/src/main/java/me/zinch/commands/Exit.java +++ b/src/main/java/me/zinch/commands/Exit.java @@ -14,6 +14,6 @@ public class Exit extends Command { @Override public String action(ProductCollection productCollection) { Console.stopApp(); - return null; + return ""; } } diff --git a/src/main/java/me/zinch/commands/Update.java b/src/main/java/me/zinch/commands/Update.java index c70c899..a384876 100644 --- a/src/main/java/me/zinch/commands/Update.java +++ b/src/main/java/me/zinch/commands/Update.java @@ -1,6 +1,9 @@ package me.zinch.commands; import me.zinch.console.Console; +import me.zinch.exceptions.CommandActionException; +import me.zinch.exceptions.ValidationException; +import me.zinch.validator.Validators; import me.zinch.wrapper.ProductCollection; import java.util.regex.Pattern; @@ -14,10 +17,18 @@ public class Update extends Command { } @Override - public String action(ProductCollection productCollection) { - var productDTO = Console.readProductDTO(); + public String action(ProductCollection productCollection) throws CommandActionException { Long id = Long.parseLong(Console.getLastCommand().split(" ")[1]); - var product = productCollection.updateProduct(id, productDTO); - return String.format("Продукт %s был изменён", product.getName()); + if (productCollection.isProductIdExists(id)) { + var productDTO = Console.readProductDTO(); + try { + Validators.validateObject(productDTO).throwIfNotValid(); + var product = productCollection.updateProduct(id, productDTO); + return String.format("Продукт %s был изменён", product.getName()); + } catch (ValidationException e) { + throw new CommandActionException(e.getMessage()); + } + } + return "Продукта с таким id не существует"; } } diff --git a/src/main/java/me/zinch/console/Console.java b/src/main/java/me/zinch/console/Console.java index 05dd45a..ea58a5f 100644 --- a/src/main/java/me/zinch/console/Console.java +++ b/src/main/java/me/zinch/console/Console.java @@ -5,6 +5,7 @@ import me.zinch.exceptions.ColorFormatException; import me.zinch.exceptions.CommandActionException; import me.zinch.exceptions.IllegalProductDtoException; import me.zinch.exceptions.UnitOfMeasureFormatException; +import me.zinch.exceptions.ValidationException; import me.zinch.files.DbController; import me.zinch.models.Color; import me.zinch.models.Coordinates; @@ -12,6 +13,8 @@ import me.zinch.models.Location; import me.zinch.models.Person; import me.zinch.models.ProductDTO; import me.zinch.models.UnitOfMeasure; +import me.zinch.validator.ValidateResult; +import me.zinch.validator.Validators; import me.zinch.wrapper.ProductCollection; import java.io.IOException; @@ -132,8 +135,16 @@ public class Console { } } - public static void run() throws IOException { - var productCollection = new ProductCollection(DbController.loadDb()); + public static void run() throws IOException, ValidationException { + var productList = DbController.loadDb(); + var validationResult = Validators.validateProductList(productList); + if (!validationResult.stream().allMatch(ValidateResult::isValid)) { + throw new ValidationException(String.join("\n", validationResult + .stream() + .map(ValidateResult::getMessage) + .toList())); + } + var productCollection = new ProductCollection(productList); System.out.println("Добро пожаловать! Для просмотра команд введите help"); while(isRunning) { System.out.print(":"); diff --git a/src/main/java/me/zinch/models/ProductDTO.java b/src/main/java/me/zinch/models/ProductDTO.java index afd68b7..75c4181 100644 --- a/src/main/java/me/zinch/models/ProductDTO.java +++ b/src/main/java/me/zinch/models/ProductDTO.java @@ -15,32 +15,32 @@ import java.time.ZonedDateTime; * Represents a Data Transfer Object (DTO) for a product with attributes such as name, coordinates, price, part number, manufacture cost, unit of measure, and owner. */ public class ProductDTO { - @NotBlank(message = "Строка name не может быть пустой или null") + @NotBlank(message = "ProductDTO: Строка name не может быть пустой или null") @JsonProperty("name") private String name; //Поле не может быть null, Строка не может быть пустой - @NotNull(message = "Поле coordinates не может быть null ") + @NotNull(message = "ProductDTO: Поле coordinates не может быть null ") @JsonProperty("coordinates") private Coordinates coordinates; //Поле не может быть null - @NotNull(message = "Поле price не может быть null") + @NotNull(message = "ProductDTO: Поле price не может быть null") @Min(value = 1, message = "Поле price не может быть null") @JsonProperty("price") private Long price; //Поле не может быть null, Значение поля должно быть больше 0 - @NotEmpty(message = "Строка partNumber не может быть пустой") - @Size(max = 82, message = "Длина строки partNumber не должна быть больше 82") + @NotEmpty(message = "ProductDTO: Строка partNumber не может быть пустой") + @Size(max = 82, message = "ProductDTO: Длина строки partNumber не должна быть больше 82") @JsonProperty("partNumber") private String partNumber; //Длина строки не должна быть больше 82, Значение этого поля должно быть уникальным, Строка не может быть пустой, Поле может быть null @JsonProperty("manufactureCost") private long manufactureCost; - @NotNull(message = "Поле unitOfMeasure не может быть null") + @NotNull(message = "ProductDTO: Поле unitOfMeasure не может быть null") @JsonProperty("unitOfMeasure") private UnitOfMeasure unitOfMeasure; //Поле не может быть null - @NotNull(message = "Поле owner не может быть null") + @NotNull(message = "ProductDTO: Поле owner не может быть null") @JsonProperty("owner") private Person owner; //Поле не может быть null diff --git a/src/main/java/me/zinch/validator/ValidateResult.java b/src/main/java/me/zinch/validator/ValidateResult.java index c508b11..feb9d70 100644 --- a/src/main/java/me/zinch/validator/ValidateResult.java +++ b/src/main/java/me/zinch/validator/ValidateResult.java @@ -12,13 +12,24 @@ import java.util.Set; public class ValidateResult { private final Set> violations; private final boolean isValid; + private final String message; public ValidateResult(Set> violations) { this.violations = violations; this.isValid = violations.isEmpty(); + this.message = null; + } + + public ValidateResult(String message) { + this.violations = null; + this.isValid = false; + this.message = message; } public String getMessage() { + if (violations == null) { + return message; + } return String.join("\n", violations.stream().map(ConstraintViolation::getMessage).toList()); } diff --git a/src/main/java/me/zinch/validator/Validators.java b/src/main/java/me/zinch/validator/Validators.java index cba1d7a..ffb9a1a 100644 --- a/src/main/java/me/zinch/validator/Validators.java +++ b/src/main/java/me/zinch/validator/Validators.java @@ -7,6 +7,7 @@ import me.zinch.models.Product; import org.hibernate.validator.HibernateValidator; import java.util.List; +import java.util.Set; /** * Utility class for performing validation operations on products. @@ -23,11 +24,20 @@ public class Validators { factory.close(); } - public static ValidateResult validateProduct(Product product) { - return new ValidateResult<>(validator.validate(product)); + public static ValidateResult validateObject(T t) { + return new ValidateResult<>(validator.validate(t)); } public static List> validateProductList(List db) { - return db.stream().map(Validators::validateProduct).toList(); + var ids = db.stream().map(Product::getId).toList(); + var partNumbers = db.stream().map(Product::getPartNumber).toList(); + var validations = new java.util.ArrayList<>(db.stream().map(Validators::validateObject).toList()); + if (ids.size() != Set.copyOf(ids).size()) { + validations.add(new ValidateResult<>("Поле id должно быть уникальным")); + } + if (partNumbers.size() != Set.copyOf(partNumbers).size()) { + validations.add(new ValidateResult<>("Поле partNumbers должно быть уникальным")); + } + return validations; } } diff --git a/src/main/java/me/zinch/wrapper/ProductCollection.java b/src/main/java/me/zinch/wrapper/ProductCollection.java index 57d62ff..d60d01c 100644 --- a/src/main/java/me/zinch/wrapper/ProductCollection.java +++ b/src/main/java/me/zinch/wrapper/ProductCollection.java @@ -3,8 +3,6 @@ package me.zinch.wrapper; import me.zinch.exceptions.ValidationException; import me.zinch.models.Product; import me.zinch.models.ProductDTO; -import me.zinch.validator.ValidateResult; -import me.zinch.validator.Validators; import java.time.Instant; import java.time.ZoneId; @@ -25,10 +23,6 @@ public class ProductCollection { public ProductCollection(List list) throws ValidationException { productList = new TreeSet<>(Comparator.comparingLong(Product::getId)); - var validationResult = Validators.validateProductList(list); - if (!validationResult.stream().allMatch(ValidateResult::isValid)) { - throw new ValidationException(String.join("\n", validationResult.stream().map(ValidateResult::getMessage).toList())); - } productList.addAll(list); idIncrementor = productList.last().getId() + 1; } @@ -44,21 +38,18 @@ public class ProductCollection { public Product addProduct(ProductDTO productDTO) { var product = productDTO.buildProduct(generateId(), ZonedDateTime.now()); - Validators.validateProduct(product).throwIfNotValid(); productList.add(product); return product; } private Product addProduct(ProductDTO productDTO, Long id, ZonedDateTime creationDate) { var product = productDTO.buildProduct(id, creationDate); - Validators.validateProduct(product).throwIfNotValid(); productList.add(product); return product; } public Product updateProduct(Long id, ProductDTO productDTO) { var product = getProductById(id); - Validators.validateProduct(product).throwIfNotValid(); productList.remove(product); return addProduct(productDTO, product.getId(), product.getCreationDate()); } @@ -79,20 +70,17 @@ public class ProductCollection { productList.clear(); } - public Optional addIfMaxPrice(ProductDTO productDTO) { - var maxPrice = productList.stream().max(Comparator.comparingLong(Product::getPrice)); - if (productList.isEmpty() || productDTO.getPrice() > maxPrice.get().getPrice()) { - return Optional.of(addProduct(productDTO)); - } - return Optional.empty(); + + public Long getMaxPrice() { + return productList.stream().max(Comparator.comparingLong(Product::getPrice)).map(Product::getPrice).orElse(null); } - public Optional addIfMinPrice(ProductDTO productDTO) { - var minPrice = productList.stream().min(Comparator.comparingLong(Product::getPrice)); - if (productList.isEmpty() || productDTO.getPrice() < minPrice.get().getPrice()) { - return Optional.of(addProduct(productDTO)); - } - return Optional.empty(); + public Long getMinPrice() { + return productList.stream().min(Comparator.comparingLong(Product::getPrice)).map(Product::getPrice).orElse(null); + } + + public boolean isProductIdExists(Long id) { + return getProductById(id) != null; } public Integer removeLover(Long id) {