Добавил исключения и их обработку

This commit is contained in:
Ivan Zinchenko 2024-03-31 15:53:10 +03:00
parent 4210204e40
commit 4188cd8e81
Signed by: zinch
GPG Key ID: 6D45AA2C8FD6A37E
20 changed files with 329 additions and 112 deletions

4
.gitignore vendored
View File

@ -31,6 +31,4 @@ bin/
.DS_Store
### Build ###
target
.db.xml.bak
target

2
db.xml
View File

@ -1 +1 @@
<Products><Product><id>1</id><name>Product 1</name><coordinates><x>100</x><y>50</y></coordinates><creationDate>1709294400.000000000</creationDate><price>50</price><partNumber>PN123</partNumber><manufactureCost>30</manufactureCost><unitOfMeasure>KILOGRAMS</unitOfMeasure><owner><name>John Doe</name><passportID>AB12345</passportID><hairColor>BLACK</hairColor><location><x>10.5</x><y>20</y><name>Home</name></location></owner></Product><Product><id>2</id><name>Product 2</name><coordinates><x>200</x><y>100</y></coordinates><creationDate>1709294700.000000000</creationDate><price>80</price><partNumber>PN456</partNumber><manufactureCost>60</manufactureCost><unitOfMeasure>CENTIMETERS</unitOfMeasure><owner><name>Alice Smith</name><passportID>CD67890</passportID><hairColor>BLUE</hairColor><location><x>20.8</x><y>30</y><name>Office</name></location></owner></Product><Product><id>3</id><name>Product 3</name><coordinates><x>150</x><y>-200</y></coordinates><creationDate>1709295000.000000000</creationDate><price>120</price><manufactureCost>90</manufactureCost><unitOfMeasure>GRAMS</unitOfMeasure><owner><name>Emma Johnson</name><passportID>EF24680</passportID><hairColor>GREEN</hairColor><location><x>30.2</x><y>40</y><name>Warehouse</name></location></owner></Product><Product><id>5</id><name>Product 5</name><coordinates><x>400</x><y>400</y></coordinates><creationDate>1709295600.000000000</creationDate><price>150</price><partNumber>PN246</partNumber><manufactureCost>100</manufactureCost><unitOfMeasure>CENTIMETERS</unitOfMeasure><owner><name>Grace Lee</name><passportID>IJ35791</passportID><hairColor>WHITE</hairColor><location><x>50.9</x><y>60</y><name>Store</name></location></owner></Product></Products>
<Products><Product><id>341</id><name>Product A</name><coordinates><x>1000</x><y>-500</y></coordinates><creationDate>1711875600.000000000</creationDate><price>1</price><partNumber>part1</partNumber><manufactureCost>1000</manufactureCost><unitOfMeasure>KILOGRAMS</unitOfMeasure><owner><name>John Doe</name><passportID>1234</passportID><hairColor>GREEN</hairColor><location><x>55.5</x><name>Home</name></location></owner></Product></Products>

117
db.xml.example Normal file
View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Products>
<Product>
<id>1</id>
<name>Product 1</name>
<coordinates>
<x>100</x>
<y>50</y>
</coordinates>
<creationDate>2024-03-01T12:00:00Z</creationDate>
<price>50</price>
<partNumber>PN123</partNumber>
<manufactureCost>30</manufactureCost>
<unitOfMeasure>KILOGRAMS</unitOfMeasure>
<owner>
<name>John Doe</name>
<passportID>AB12345</passportID>
<hairColor>BLACK</hairColor>
<location>
<x>10.5</x>
<y>20</y>
<name>Home</name>
</location>
</owner>
</Product>
<Product>
<id>2</id>
<name>Product 2</name>
<coordinates>
<x>200</x>
<y>100</y>
</coordinates>
<creationDate>2024-03-01T12:05:00Z</creationDate>
<price>80</price>
<partNumber>PN456</partNumber>
<manufactureCost>60</manufactureCost>
<unitOfMeasure>CENTIMETERS</unitOfMeasure>
<owner>
<name>Alice Smith</name>
<passportID>CD67890</passportID>
<hairColor>BLUE</hairColor>
<location>
<x>20.8</x>
<y>30</y>
<name>Office</name>
</location>
</owner>
</Product>
<Product>
<id>3</id>
<name>Product 3</name>
<coordinates>
<x>150</x>
<y>-200</y>
</coordinates>
<creationDate>2024-03-01T12:10:00Z</creationDate>
<price>120</price>
<manufactureCost>90</manufactureCost>
<unitOfMeasure>GRAMS</unitOfMeasure>
<owner>
<name>Emma Johnson</name>
<passportID>EF24680</passportID>
<hairColor>GREEN</hairColor>
<location>
<x>30.2</x>
<y>40</y>
<name>Warehouse</name>
</location>
</owner>
</Product>
<Product>
<id>4</id>
<name>Product 4</name>
<coordinates>
<x>300</x>
<y>-300</y>
</coordinates>
<creationDate>2024-03-01T12:15:00Z</creationDate>
<price>200</price>
<partNumber>PN789</partNumber>
<manufactureCost>150</manufactureCost>
<unitOfMeasure>KILOGRAMS</unitOfMeasure>
<owner>
<name>Bob Brown</name>
<passportID>GH13579</passportID>
<hairColor>ORANGE</hairColor>
<location>
<x>40.6</x>
<y>50</y>
<name>Factory</name>
</location>
</owner>
</Product>
<Product>
<id>5</id>
<name>Product 5</name>
<coordinates>
<x>400</x>
<y>400</y>
</coordinates>
<creationDate>2024-03-01T12:20:00Z</creationDate>
<price>150</price>
<partNumber>PN246</partNumber>
<manufactureCost>100</manufactureCost>
<unitOfMeasure>CENTIMETERS</unitOfMeasure>
<owner>
<name>Grace Lee</name>
<passportID>IJ35791</passportID>
<hairColor>WHITE</hairColor>
<location>
<x>50.9</x>
<y>60</y>
<name>Store</name>
</location>
</owner>
</Product>
</Products>

View File

@ -1,12 +1,19 @@
package me.zinch;
import me.zinch.console.Console;
import me.zinch.files.DbController;
import me.zinch.wrapper.ProductCollection;
import me.zinch.exceptions.ValidationException;
import java.io.IOException;
public class App {
public static void main(String[] args) {
ProductCollection productCollection = new ProductCollection(DbController.loadDb());
Console.run(productCollection);
try {
Console.run();
} catch (ValidationException e) {
System.out.println("Ошибка при валидации БД. Некоторые данные не валидны.");
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}

View File

@ -1,6 +1,7 @@
package me.zinch.commands;
import me.zinch.console.Console;
import me.zinch.exceptions.CommandActionException;
import me.zinch.wrapper.ProductCollection;
import java.util.regex.Pattern;
@ -11,7 +12,7 @@ public class Add extends Command {
}
@Override
public void action(ProductCollection productCollection) {
public void action(ProductCollection productCollection) throws CommandActionException {
var productDTO = Console.readProductDTO();
var product = productCollection.addProduct(productDTO);
System.out.format("Продукт %s был добавлен под id %d", product.getName(), product.getId());

View File

@ -1,5 +1,6 @@
package me.zinch.commands;
import me.zinch.exceptions.CommandActionException;
import me.zinch.wrapper.ProductCollection;
import java.util.regex.Pattern;
@ -21,21 +22,21 @@ public abstract class Command {
this.pattern = Pattern.compile("^" + name);
}
public String getName() {
public final String getName() {
return name;
}
public String getDescription() {
public final String getDescription() {
return description;
}
public Pattern getPattern() {
public final Pattern getPattern() {
return pattern;
}
public boolean checkPattern(String input) {
public final boolean checkPattern(String input) {
return pattern.matcher(input).matches();
}
public abstract void action(ProductCollection productCollection);
public abstract void action(ProductCollection productCollection) throws CommandActionException;
}

View File

@ -1,16 +1,23 @@
package me.zinch.commands;
import me.zinch.exceptions.CommandActionException;
import me.zinch.files.DbController;
import me.zinch.wrapper.ProductCollection;
import java.io.IOException;
public class Save extends Command {
public Save() {
super("save", "сохранить коллекцию в файл");
}
@Override
public void action(ProductCollection productCollection) {
DbController.saveDb(productCollection.toList());
System.out.println("Коллекция была сохранена");
public void action(ProductCollection productCollection) throws CommandActionException {
try {
DbController.saveDb(productCollection.toList());
System.out.println("Коллекция была сохранена");
} catch (IOException e) {
throw new CommandActionException(e.getMessage());
}
}
}

View File

@ -1,6 +1,9 @@
package me.zinch.console;
import me.zinch.commands.CommandManager;
import me.zinch.exceptions.CommandActionException;
import me.zinch.exceptions.IllegalProductDtoException;
import me.zinch.files.DbController;
import me.zinch.models.Color;
import me.zinch.models.Coordinates;
import me.zinch.models.Location;
@ -9,6 +12,7 @@ import me.zinch.models.ProductDTO;
import me.zinch.models.UnitOfMeasure;
import me.zinch.wrapper.ProductCollection;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
@ -18,8 +22,6 @@ public class Console {
private static boolean isRunning = true;
private static final List<String> history = new ArrayList<>();
private Console() {}
private static void appendHistory(String input) {
history.add(input);
}
@ -32,63 +34,68 @@ public class Console {
return history.get(history.size() - 1);
}
public static ProductDTO readProductDTO() {
var productDTO = new ProductDTO();
System.out.println("Заполните следующие поля: ");
System.out.print("Название: ");
productDTO.setName(scanner.nextLine().trim());
System.out.print("Координата x: ");
long x = Long.parseLong(scanner.nextLine().trim());
System.out.print("Координата y: ");
long y = Long.parseLong(scanner.nextLine().trim());
productDTO.setCoordinates(new Coordinates(x, y));
System.out.print("Цена: ");
productDTO.setPrice(Long.parseLong(scanner.nextLine().trim()));
System.out.print("Номер части: ");
productDTO.setPartNumber(scanner.nextLine().trim());
System.out.print("Себестоимость: ");
productDTO.setManufactureCost(Long.parseLong(scanner.nextLine().trim()));
System.out.print("Единица измерения(Килограммы[0], Сантиметры[1], Граммы[2]): ");
public static ProductDTO readProductDTO() throws IllegalProductDtoException {
try {
productDTO.setUnitOfMeasure(UnitOfMeasure.create(Integer.parseInt(scanner.nextLine().trim())));
var productDTO = new ProductDTO();
System.out.println("Заполните следующие поля: ");
System.out.print("Название: ");
productDTO.setName(scanner.nextLine().trim());
System.out.print("Координата x: ");
long x = Long.parseLong(scanner.nextLine().trim());
System.out.print("Координата y: ");
long y = Long.parseLong(scanner.nextLine().trim());
productDTO.setCoordinates(new Coordinates(x, y));
System.out.print("Цена: ");
productDTO.setPrice(Long.parseLong(scanner.nextLine().trim()));
System.out.print("Номер части: ");
productDTO.setPartNumber(scanner.nextLine().trim());
System.out.print("Себестоимость: ");
productDTO.setManufactureCost(Long.parseLong(scanner.nextLine().trim()));
System.out.print("Единица измерения(Килограммы[0], Сантиметры[1], Граммы[2]): ");
try {
productDTO.setUnitOfMeasure(UnitOfMeasure.create(Integer.parseInt(scanner.nextLine().trim())));
} catch (NumberFormatException e) {
productDTO.setUnitOfMeasure(UnitOfMeasure.create(scanner.nextLine().trim()));
}
System.out.print("Имя владельца: ");
var ownerName = scanner.nextLine().trim();
System.out.print("Данные паспорта: ");
var passportId = scanner.nextLine().trim();
System.out.print("Цвет волос(Зелёный[0], Чёрный[1], Синий[2], Оранжевый[3], Белый[4]): ");
Color color;
try {
color = Color.create(Integer.parseInt(scanner.nextLine().trim()));
} catch (NumberFormatException e) {
color = Color.create(scanner.nextLine().trim());
}
System.out.print("Координата x локации: ");
var locationX = Float.parseFloat(scanner.nextLine().trim());
System.out.print("Координата y локации: ");
var locationY = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Название: ");
var locationName = scanner.nextLine().trim();
productDTO.setOwner(new Person(ownerName, passportId, color, new Location(locationX, locationY, locationName)));
return productDTO;
} catch (NumberFormatException e) {
productDTO.setUnitOfMeasure(UnitOfMeasure.create(scanner.nextLine().trim()));
throw new IllegalProductDtoException();
}
System.out.print("Имя владельца: ");
var ownerName = scanner.nextLine().trim();
System.out.print("Данные паспорта: ");
var passportId = scanner.nextLine().trim();
System.out.print("Цвет волос(Зелёный[0], Чёрный[1], Синий[2], Оранжевый[3], Белый[4]): ");
Color color;
try {
color = Color.create(Integer.parseInt(scanner.nextLine().trim()));
} catch (NumberFormatException e) {
color = Color.create(scanner.nextLine().trim());
}
System.out.print("Координата x локации: ");
var locationX = Float.parseFloat(scanner.nextLine().trim());
System.out.print("Координата y локации: ");
var locationY = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Название: ");
var locationName = scanner.nextLine().trim();
productDTO.setOwner(new Person(ownerName, passportId, color, new Location(locationX, locationY, locationName)));
return productDTO;
}
public static void run(ProductCollection productCollection) {
public static void run() throws IOException {
var productCollection = new ProductCollection(DbController.loadDb());
System.out.println("Добро пожаловать! Для просмотра команд введите help");
while(isRunning) {
System.out.print(":");
var input = scanner.nextLine().trim();
var command = CommandManager.getCommandByInput(input);
if (command.isPresent()) {
appendHistory(input);
command.get().action(productCollection);
try {
command.get().action(productCollection);
} catch (CommandActionException e) {
System.out.println(e.getMessage());
}
} else {
System.out.println("Такой команды не существует. Напишите help, чтобы посмотреть список доступных команд.");
}

View File

@ -0,0 +1,15 @@
package me.zinch.exceptions;
public class CommandActionException extends RuntimeException {
public CommandActionException() {
super("Ошибка во время выполнения команды");
}
public CommandActionException(String message) {
super(message);
}
public CommandActionException(Throwable e) {
super(e);
}
}

View File

@ -0,0 +1,9 @@
package me.zinch.exceptions;
import java.io.IOException;
public class DbInitializationException extends IOException {
public DbInitializationException() {
super("Ошибка! Не удалось инициализировать БД. Проверьте, что структура БД верна.");
}
}

View File

@ -0,0 +1,15 @@
package me.zinch.exceptions;
public class IllegalProductDtoException extends CommandActionException {
public IllegalProductDtoException() {
super("Ошибка при создании или изменении продукта. Были введены некорректные значения.");
}
public IllegalProductDtoException(String message) {
super(message);
}
public IllegalProductDtoException(Throwable e) {
super(e);
}
}

View File

@ -0,0 +1,13 @@
package me.zinch.exceptions;
public class ValidationException extends jakarta.validation.ValidationException {
public ValidationException() {}
public ValidationException(String message) {
super(message);
}
public ValidationException(Throwable e) {
super(e);
}
}

View File

@ -1,10 +1,12 @@
package me.zinch.files;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import me.zinch.exceptions.DbInitializationException;
import me.zinch.models.Product;
import java.io.BufferedInputStream;
@ -26,7 +28,7 @@ public class DbController {
xmlMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
}
public static class Products {
private static class Products {
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "Product")
private List<Product> products;
@ -42,27 +44,28 @@ public class DbController {
}
}
public static List<Product> loadDb() {
public static List<Product> loadDb() throws IOException {
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(path));
Products collection = xmlMapper.readValue(bufferedInputStream, Products.class);
return collection.getProducts();
} catch (FileNotFoundException e) {
System.err.println("Ошибка! Файл не найден.");
throw new FileNotFoundException("Не удалось найти файл " + path);
} catch (DatabindException e) {
throw new DbInitializationException();
} catch (IOException e) {
System.err.println("Произошла неожиданная ошибка во время работы с файлом!");
throw new IOException("Произошла неожиданная ошибка во время работы с файлом!");
}
return List.of();
}
public static void saveDb(List<Product> list) {
public static void saveDb(List<Product> list) throws IOException {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path));
xmlMapper.writeValue(outputStreamWriter, new Products(list));
} catch (FileNotFoundException e) {
System.err.println("Ошибка! Файл не найден");
throw new FileNotFoundException(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
throw new IOException(e);
}
}
}

View File

@ -8,12 +8,12 @@ import jakarta.validation.constraints.NotNull;
import java.util.Objects;
public class Coordinates {
@Max(value = 883, message = "Максимальное значение поля x: 883")
@Max(value = 883, message = "Coordinates: Максимальное значение координаты x: 883")
@JsonProperty("x")
private long x; //Максимальное значение поля: 883
@NotNull(message = "Поле не может быть null")
@Min(value = -427, message = "Значение поля y должно быть больше -427")
@NotNull(message = "Coordinates: Поле не может быть null")
@Min(value = -427, message = "Значение координаты y должно быть больше -427")
@JsonProperty("y")
private Long y; //Значение поля должно быть больше -427, Поле не может быть null

View File

@ -1,8 +1,8 @@
package me.zinch.models;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import me.zinch.validator.NotEmpty;
import java.util.Objects;
@ -10,11 +10,11 @@ public class Location {
@JsonProperty("x")
private float x;
@NotNull(message = "Поле y не может быть null")
@NotNull(message = "Location: Координата y не может быть null")
@JsonProperty("y")
private Integer y; //Поле не может быть null
@NotBlank(message = "Строка name не может быть пустой или null")
@NotEmpty(message = "Location: Название локации не может быть пустым или null")
@JsonProperty("name")
private String name; //Строка не может быть пустой, Поле может быть null

View File

@ -8,20 +8,18 @@ import jakarta.validation.constraints.Size;
import java.util.Objects;
public class Person {
@NotBlank(message = "Строка name не может быть пустой или null")
@NotBlank(message = "Person: Имя персоны не может быть пустым или null")
@JsonProperty("name")
private String name; //Поле не может быть null, Строка не может быть пустой
@NotNull(message = "Поле passportID не может быть null")
@NotNull(message = "Person: Поле passportID не может быть null")
@Size(min = 5, max = 22, message = "Длина строки passportID должна быть не меньше 5 и не должна быть больше 22")
@JsonProperty("passportID")
private String passportID; //Длина строки должна быть не меньше 5, Длина строки не должна быть больше 22, Поле не может быть null
@NotNull(message = "Поле hairColor может быть null")
@JsonProperty("hairColor")
private Color hairColor; //Поле может быть null
@NotNull(message = "Поле location может быть null")
@JsonProperty("location")
private Location location; //Поле может быть null

View File

@ -11,41 +11,41 @@ import java.time.ZonedDateTime;
import java.util.Objects;
public class Product {
@NotNull(message = "Поле id не может быть null")
@Min(value = 1, message = "Значение поля id должно быть больше 0")
@NotNull(message = "Product: Поле id не может быть null")
@Min(value = 1, message = "Product: Значение поля id должно быть больше 0")
@JsonProperty("id")
private Long id; //Поле не может быть null, Значение поля должно быть больше 0, Значение этого поля должно быть уникальным, Значение этого поля должно генерироваться автоматически
@NotBlank(message = "Строка name не может быть пустой или null")
@NotBlank(message = "Product: Строка name не может быть пустой или null")
@JsonProperty("name")
private String name; //Поле не может быть null, Строка не может быть пустой
@NotNull(message = "Поле coordinates не может быть null ")
@NotNull(message = "Product: Поле coordinates не может быть null ")
@JsonProperty("coordinates")
private Coordinates coordinates; //Поле не может быть null
@NotNull(message = "Поле creationDate не может быть null")
@NotNull(message = "Product: Поле creationDate не может быть null")
@JsonProperty("creationDate")
private ZonedDateTime creationDate; //Поле не может быть null, Значение этого поля должно генерироваться автоматически
@NotNull(message = "Поле price не может быть null")
@Min(value = 1, message = "Поле price не может быть null")
@NotNull(message = "Product: Поле price не может быть null")
@Min(value = 1, message = "Product: Значение поля price должно быть больше 0")
@JsonProperty("price")
private Long price; //Поле не может быть null, Значение поля должно быть больше 0
@NotEmpty(message = "Строка partNumber не может быть пустой")
@Size(max = 82, message = "Длина строки partNumber не должна быть больше 82")
@NotEmpty(message = "Product: Строка partNumber не может быть пустой")
@Size(max = 82, message = "Product: Длина строки partNumber не должна быть больше 82")
@JsonProperty("partNumber")
private String partNumber; //Длина строки не должна быть больше 82, Значение этого поля должно быть уникальным, Строка не может быть пустой, Поле может быть null
@JsonProperty("manufactureCost")
private long manufactureCost;
@NotNull(message = "Поле unitOfMeasure не может быть null")
@NotNull(message = "Product: Поле unitOfMeasure не может быть null")
@JsonProperty("unitOfMeasure")
private UnitOfMeasure unitOfMeasure; //Поле не может быть null
@NotNull(message = "Поле owner не может быть null")
@NotNull(message = "Product: Поле owner не может быть null")
@JsonProperty("owner")
private Person owner; //Поле не может быть null

View File

@ -0,0 +1,28 @@
package me.zinch.validator;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ValidationException;
import java.util.Set;
public class ValidateResult<T> {
private final Set<ConstraintViolation<T>> violations;
private final boolean isValid;
public ValidateResult(Set<ConstraintViolation<T>> violations) {
this.violations = violations;
this.isValid = violations.isEmpty();
}
public String getMessage() {
return String.join("\n", violations.stream().map(ConstraintViolation::getMessage).toList());
}
public boolean isValid() {
return isValid;
}
public void throwIfNotValid() throws ValidationException {
if (!isValid) throw new ValidationException(getMessage());
}
}

View File

@ -1,6 +1,5 @@
package me.zinch.validator;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
@ -8,7 +7,6 @@ import me.zinch.models.Product;
import org.hibernate.validator.HibernateValidator;
import java.util.List;
import java.util.Set;
public class Validators {
private static final Validator validator;
@ -16,22 +14,17 @@ public class Validators {
static {
ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
.configure()
.showValidatedValuesInTraceLogs(false)
.showValidatedValuesInTraceLogs(true)
.buildValidatorFactory();
validator = factory.usingContext().getValidator();
factory.close();
}
public static boolean validateProduct(Product product) {
Set<ConstraintViolation<Product>> violations = validator.validate(product);
for (ConstraintViolation<Product> violation : violations) {
System.out.println(violation.getMessage());
}
return violations.isEmpty();
public static ValidateResult<Product> validateProduct(Product product) {
return new ValidateResult<>(validator.validate(product));
}
public static boolean validateProductList(List<Product> db) {
// TODO: validate unique ID
return db.stream().allMatch(Validators::validateProduct);
public static List<ValidateResult<Product>> validateProductList(List<Product> db) {
return db.stream().map(Validators::validateProduct).toList();
}
}

View File

@ -1,7 +1,9 @@
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;
@ -18,14 +20,14 @@ public class ProductCollection {
private final TreeSet<Product> productList;
private Long idIncrementor;
public ProductCollection(List<Product> list) {
public ProductCollection(List<Product> list) throws ValidationException {
productList = new TreeSet<>(Comparator.comparingLong(Product::getId));
if (Validators.validateProductList(list)) {
productList.addAll(list);
idIncrementor = productList.last().getId() + 1;
} else {
System.exit(1);
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;
}
private Long generateId() {
@ -39,18 +41,21 @@ 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());
}