Добавил исключения и их обработку
This commit is contained in:
parent
4210204e40
commit
4188cd8e81
2
.gitignore
vendored
2
.gitignore
vendored
@ -32,5 +32,3 @@ bin/
|
||||
|
||||
### Build ###
|
||||
target
|
||||
|
||||
.db.xml.bak
|
||||
2
db.xml
2
db.xml
@ -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
117
db.xml.example
Normal 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>
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
public void action(ProductCollection productCollection) throws CommandActionException {
|
||||
try {
|
||||
DbController.saveDb(productCollection.toList());
|
||||
System.out.println("Коллекция была сохранена");
|
||||
} catch (IOException e) {
|
||||
throw new CommandActionException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,18 +34,17 @@ public class Console {
|
||||
return history.get(history.size() - 1);
|
||||
}
|
||||
|
||||
public static ProductDTO readProductDTO() {
|
||||
public static ProductDTO readProductDTO() throws IllegalProductDtoException {
|
||||
try {
|
||||
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("Номер части: ");
|
||||
@ -56,7 +57,6 @@ public class Console {
|
||||
} catch (NumberFormatException e) {
|
||||
productDTO.setUnitOfMeasure(UnitOfMeasure.create(scanner.nextLine().trim()));
|
||||
}
|
||||
|
||||
System.out.print("Имя владельца: ");
|
||||
var ownerName = scanner.nextLine().trim();
|
||||
System.out.print("Данные паспорта: ");
|
||||
@ -68,7 +68,6 @@ public class Console {
|
||||
} catch (NumberFormatException e) {
|
||||
color = Color.create(scanner.nextLine().trim());
|
||||
}
|
||||
|
||||
System.out.print("Координата x локации: ");
|
||||
var locationX = Float.parseFloat(scanner.nextLine().trim());
|
||||
System.out.print("Координата y локации: ");
|
||||
@ -77,18 +76,26 @@ public class Console {
|
||||
var locationName = scanner.nextLine().trim();
|
||||
|
||||
productDTO.setOwner(new Person(ownerName, passportId, color, new Location(locationX, locationY, locationName)));
|
||||
|
||||
return productDTO;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalProductDtoException();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
try {
|
||||
command.get().action(productCollection);
|
||||
} catch (CommandActionException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println("Такой команды не существует. Напишите help, чтобы посмотреть список доступных команд.");
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package me.zinch.exceptions;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DbInitializationException extends IOException {
|
||||
public DbInitializationException() {
|
||||
super("Ошибка! Не удалось инициализировать БД. Проверьте, что структура БД верна.");
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
13
src/main/java/me/zinch/exceptions/ValidationException.java
Normal file
13
src/main/java/me/zinch/exceptions/ValidationException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
28
src/main/java/me/zinch/validator/ValidateResult.java
Normal file
28
src/main/java/me/zinch/validator/ValidateResult.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)) {
|
||||
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;
|
||||
} else {
|
||||
System.exit(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());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user