diff --git a/.gitignore b/.gitignore
index 60fba23..1771f2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,4 @@ bin/
.DS_Store
### Build ###
-target
-
-.db.xml.bak
\ No newline at end of file
+target
\ No newline at end of file
diff --git a/db.xml b/db.xml
index fe38691..d920776 100644
--- a/db.xml
+++ b/db.xml
@@ -1 +1 @@
-1Product 1100501709294400.00000000050PN12330KILOGRAMSJohn DoeAB12345BLACK10.520Home2Product 22001001709294700.00000000080PN45660CENTIMETERSAlice SmithCD67890BLUE20.830Office3Product 3150-2001709295000.00000000012090GRAMSEmma JohnsonEF24680GREEN30.240Warehouse5Product 54004001709295600.000000000150PN246100CENTIMETERSGrace LeeIJ35791WHITE50.960Store
\ No newline at end of file
+341Product A1000-5001711875600.0000000001part11000KILOGRAMSJohn Doe1234GREEN55.5Home
\ No newline at end of file
diff --git a/db.xml.example b/db.xml.example
new file mode 100644
index 0000000..3885e88
--- /dev/null
+++ b/db.xml.example
@@ -0,0 +1,117 @@
+
+
+
+ 1
+ Product 1
+
+ 100
+ 50
+
+ 2024-03-01T12:00:00Z
+ 50
+ PN123
+ 30
+ KILOGRAMS
+
+ John Doe
+ AB12345
+ BLACK
+
+ 10.5
+ 20
+ Home
+
+
+
+
+ 2
+ Product 2
+
+ 200
+ 100
+
+ 2024-03-01T12:05:00Z
+ 80
+ PN456
+ 60
+ CENTIMETERS
+
+ Alice Smith
+ CD67890
+ BLUE
+
+ 20.8
+ 30
+ Office
+
+
+
+
+ 3
+ Product 3
+
+ 150
+ -200
+
+ 2024-03-01T12:10:00Z
+ 120
+ 90
+ GRAMS
+
+ Emma Johnson
+ EF24680
+ GREEN
+
+ 30.2
+ 40
+ Warehouse
+
+
+
+
+ 4
+ Product 4
+
+ 300
+ -300
+
+ 2024-03-01T12:15:00Z
+ 200
+ PN789
+ 150
+ KILOGRAMS
+
+ Bob Brown
+ GH13579
+ ORANGE
+
+ 40.6
+ 50
+ Factory
+
+
+
+
+ 5
+ Product 5
+
+ 400
+ 400
+
+ 2024-03-01T12:20:00Z
+ 150
+ PN246
+ 100
+ CENTIMETERS
+
+ Grace Lee
+ IJ35791
+ WHITE
+
+ 50.9
+ 60
+ Store
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/me/zinch/App.java b/src/main/java/me/zinch/App.java
index 760e856..8b94c36 100644
--- a/src/main/java/me/zinch/App.java
+++ b/src/main/java/me/zinch/App.java
@@ -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());
+ }
}
}
diff --git a/src/main/java/me/zinch/commands/Add.java b/src/main/java/me/zinch/commands/Add.java
index ff91db1..2a866bf 100644
--- a/src/main/java/me/zinch/commands/Add.java
+++ b/src/main/java/me/zinch/commands/Add.java
@@ -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());
diff --git a/src/main/java/me/zinch/commands/Command.java b/src/main/java/me/zinch/commands/Command.java
index 14e37a3..b73b95d 100644
--- a/src/main/java/me/zinch/commands/Command.java
+++ b/src/main/java/me/zinch/commands/Command.java
@@ -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;
}
diff --git a/src/main/java/me/zinch/commands/Save.java b/src/main/java/me/zinch/commands/Save.java
index 23537da..0ec205b 100644
--- a/src/main/java/me/zinch/commands/Save.java
+++ b/src/main/java/me/zinch/commands/Save.java
@@ -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());
+ }
}
}
diff --git a/src/main/java/me/zinch/console/Console.java b/src/main/java/me/zinch/console/Console.java
index beae45d..4602ce4 100644
--- a/src/main/java/me/zinch/console/Console.java
+++ b/src/main/java/me/zinch/console/Console.java
@@ -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 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, чтобы посмотреть список доступных команд.");
}
diff --git a/src/main/java/me/zinch/exceptions/CommandActionException.java b/src/main/java/me/zinch/exceptions/CommandActionException.java
new file mode 100644
index 0000000..9b780fb
--- /dev/null
+++ b/src/main/java/me/zinch/exceptions/CommandActionException.java
@@ -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);
+ }
+}
diff --git a/src/main/java/me/zinch/exceptions/DbInitializationException.java b/src/main/java/me/zinch/exceptions/DbInitializationException.java
new file mode 100644
index 0000000..1351143
--- /dev/null
+++ b/src/main/java/me/zinch/exceptions/DbInitializationException.java
@@ -0,0 +1,9 @@
+package me.zinch.exceptions;
+
+import java.io.IOException;
+
+public class DbInitializationException extends IOException {
+ public DbInitializationException() {
+ super("Ошибка! Не удалось инициализировать БД. Проверьте, что структура БД верна.");
+ }
+}
diff --git a/src/main/java/me/zinch/exceptions/IllegalProductDtoException.java b/src/main/java/me/zinch/exceptions/IllegalProductDtoException.java
new file mode 100644
index 0000000..e1c780a
--- /dev/null
+++ b/src/main/java/me/zinch/exceptions/IllegalProductDtoException.java
@@ -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);
+ }
+}
diff --git a/src/main/java/me/zinch/exceptions/ValidationException.java b/src/main/java/me/zinch/exceptions/ValidationException.java
new file mode 100644
index 0000000..00b6ab9
--- /dev/null
+++ b/src/main/java/me/zinch/exceptions/ValidationException.java
@@ -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);
+ }
+}
diff --git a/src/main/java/me/zinch/files/DbController.java b/src/main/java/me/zinch/files/DbController.java
index 4cad167..ef46f98 100644
--- a/src/main/java/me/zinch/files/DbController.java
+++ b/src/main/java/me/zinch/files/DbController.java
@@ -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 products;
@@ -42,27 +44,28 @@ public class DbController {
}
}
- public static List loadDb() {
+ public static List 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 list) {
+ public static void saveDb(List 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);
}
}
}
diff --git a/src/main/java/me/zinch/models/Coordinates.java b/src/main/java/me/zinch/models/Coordinates.java
index 52eae4f..16c3b6c 100644
--- a/src/main/java/me/zinch/models/Coordinates.java
+++ b/src/main/java/me/zinch/models/Coordinates.java
@@ -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
diff --git a/src/main/java/me/zinch/models/Location.java b/src/main/java/me/zinch/models/Location.java
index b550135..d2f2ae4 100644
--- a/src/main/java/me/zinch/models/Location.java
+++ b/src/main/java/me/zinch/models/Location.java
@@ -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
diff --git a/src/main/java/me/zinch/models/Person.java b/src/main/java/me/zinch/models/Person.java
index 3634b89..8e55e34 100644
--- a/src/main/java/me/zinch/models/Person.java
+++ b/src/main/java/me/zinch/models/Person.java
@@ -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
diff --git a/src/main/java/me/zinch/models/Product.java b/src/main/java/me/zinch/models/Product.java
index 7b09cd8..48d6fa0 100644
--- a/src/main/java/me/zinch/models/Product.java
+++ b/src/main/java/me/zinch/models/Product.java
@@ -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
diff --git a/src/main/java/me/zinch/validator/ValidateResult.java b/src/main/java/me/zinch/validator/ValidateResult.java
new file mode 100644
index 0000000..b103d98
--- /dev/null
+++ b/src/main/java/me/zinch/validator/ValidateResult.java
@@ -0,0 +1,28 @@
+package me.zinch.validator;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ValidationException;
+
+import java.util.Set;
+
+public class ValidateResult {
+ private final Set> violations;
+ private final boolean isValid;
+
+ public ValidateResult(Set> 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());
+ }
+}
diff --git a/src/main/java/me/zinch/validator/Validators.java b/src/main/java/me/zinch/validator/Validators.java
index 9c29d07..29e719a 100644
--- a/src/main/java/me/zinch/validator/Validators.java
+++ b/src/main/java/me/zinch/validator/Validators.java
@@ -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> violations = validator.validate(product);
- for (ConstraintViolation violation : violations) {
- System.out.println(violation.getMessage());
- }
- return violations.isEmpty();
+ public static ValidateResult validateProduct(Product product) {
+ return new ValidateResult<>(validator.validate(product));
}
- public static boolean validateProductList(List db) {
- // TODO: validate unique ID
- return db.stream().allMatch(Validators::validateProduct);
+ public static List> validateProductList(List db) {
+ return db.stream().map(Validators::validateProduct).toList();
}
}
diff --git a/src/main/java/me/zinch/wrapper/ProductCollection.java b/src/main/java/me/zinch/wrapper/ProductCollection.java
index c3b9ac4..36da985 100644
--- a/src/main/java/me/zinch/wrapper/ProductCollection.java
+++ b/src/main/java/me/zinch/wrapper/ProductCollection.java
@@ -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 productList;
private Long idIncrementor;
- public ProductCollection(List list) {
+ public ProductCollection(List 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());
}