From 94ccc698a7afcd57051385cd1af69501738ec503 Mon Sep 17 00:00:00 2001 From: Ivan Zinchenko Date: Fri, 29 Mar 2024 22:34:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B1=D0=B4=20=D0=B8=20=D0=B5=D1=91=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- MANIFEST.mf | 3 - Makefile | 6 - Notes.md | 4 + README.md | 99 +++++++++++++ db.xml | 117 +++++++++++++++ pom.xml | 51 +++++++ src/Main.java | 5 - src/main/java/me/zinch/App.java | 18 +++ src/main/java/me/zinch/commands/Command.java | 29 ++++ .../java/me/zinch/files/DbController.java | 41 ++++++ src/main/java/me/zinch/models/Color.java | 9 ++ .../java/me/zinch/models/Coordinates.java | 40 +++++ src/main/java/me/zinch/models/Location.java | 54 +++++++ src/main/java/me/zinch/models/Person.java | 50 +++++++ src/main/java/me/zinch/models/Product.java | 137 ++++++++++++++++++ .../java/me/zinch/models/UnitOfMeasure.java | 7 + .../java/me/zinch/validator/NotEmpty.java | 18 +++ .../me/zinch/validator/NotEmptyValidator.java | 11 ++ .../java/me/zinch/validator/Validators.java | 36 +++++ 20 files changed, 725 insertions(+), 15 deletions(-) delete mode 100644 MANIFEST.mf delete mode 100644 Makefile create mode 100644 Notes.md create mode 100644 README.md create mode 100644 db.xml create mode 100644 pom.xml delete mode 100644 src/Main.java create mode 100644 src/main/java/me/zinch/App.java create mode 100644 src/main/java/me/zinch/commands/Command.java create mode 100644 src/main/java/me/zinch/files/DbController.java create mode 100644 src/main/java/me/zinch/models/Color.java create mode 100644 src/main/java/me/zinch/models/Coordinates.java create mode 100644 src/main/java/me/zinch/models/Location.java create mode 100644 src/main/java/me/zinch/models/Person.java create mode 100644 src/main/java/me/zinch/models/Product.java create mode 100644 src/main/java/me/zinch/models/UnitOfMeasure.java create mode 100644 src/main/java/me/zinch/validator/NotEmpty.java create mode 100644 src/main/java/me/zinch/validator/NotEmptyValidator.java create mode 100644 src/main/java/me/zinch/validator/Validators.java diff --git a/.gitignore b/.gitignore index 82b7e88..1771f2c 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,7 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store + +### Build ### +target \ No newline at end of file diff --git a/MANIFEST.mf b/MANIFEST.mf deleted file mode 100644 index 6f7f37a..0000000 --- a/MANIFEST.mf +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Created-By: zinch -Main-class: Main diff --git a/Makefile b/Makefile deleted file mode 100644 index 4effb7d..0000000 --- a/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - rm -rf target - javac -d target -sourcepath src src/Main.java src/**/* - cd target; jar cfm app.jar ../MANIFEST.mf *.class ./**/*.class - mv target/app.jar ./ - rm -rf target diff --git a/Notes.md b/Notes.md new file mode 100644 index 0000000..faf35ae --- /dev/null +++ b/Notes.md @@ -0,0 +1,4 @@ +### Этапы работы программы + +1. Проверка файла с базой данных +2. Пользовательский ввод \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..94b0889 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# Лабораторная работа №5 + +## Выполнил +> ФИ: Зинченко Иван +> +> ИСУ: 408657 +> +> Вариант: 1632 + +## Задание +Реализовать консольное приложение, которое реализует управление коллекцией объектов в интерактивном режиме. +В коллекции необходимо хранить объекты класса `Product`, описание которого приведено ниже. + +Разработанная программа должна удовлетворять следующим требованиям: +- Класс, коллекцией экземпляров которого управляет программа, должен реализовывать сортировку по умолчанию. +- Все требования к полям класса (указанные в виде комментариев) должны быть выполнены. +- Для хранения необходимо использовать коллекцию типа `java.util.TreeSet` +- При запуске приложения коллекция должна автоматически заполняться значениями из файла. +- Имя файла должно передаваться программе с помощью: переменная окружения. +- Данные должны храниться в файле в формате `xml` +- Чтение данных из файла необходимо реализовать с помощью класса `java.io.BufferedInputStream` +- Запись данных в файл необходимо реализовать с помощью класса `java.io.OutputStreamWriter` +- Все классы в программе должны быть задокументированы в формате javadoc. +- Программа должна корректно работать с неправильными данными (ошибки пользовательского ввода, отсутсвие прав доступа к файлу и т.п.). + +В интерактивном режиме программа должна поддерживать выполнение следующих команд: +- `help` : вывести справку по доступным командам +- `info` : вывести в стандартный поток вывода информацию о коллекции (тип, дата инициализации, количество элементов и т.д.) +- `show` : вывести в стандартный поток вывода все элементы коллекции в строковом представлении +- `add {element}` : добавить новый элемент в коллекцию +- `update id {element}` : обновить значение элемента коллекции, id которого равен заданному +- `remove_by_id id` : удалить элемент из коллекции по его id +- `clear` : очистить коллекцию +- `save` : сохранить коллекцию в файл +- `execute_script file_name` : считать и исполнить скрипт из указанного файла. В скрипте содержатся команды в таком же виде, в котором их вводит пользователь в интерактивном режиме. +- `exit` : завершить программу (без сохранения в файл) +- `add_if_max {element}` : добавить новый элемент в коллекцию, если его значение превышает значение наибольшего элемента этой коллекции +- `add_if_min {element}` : добавить новый элемент в коллекцию, если его значение меньше, чем у наименьшего элемента этой коллекции +- `remove_lower {element}` : удалить из коллекции все элементы, меньшие, чем заданный +- `filter_contains_name name` : вывести элементы, значение поля name которых содержит заданную подстроку +- `print_ascending` : вывести элементы коллекции в порядке возрастания +- `print_unique_manufacture_cost` : вывести уникальные значения поля manufactureCost всех элементов в коллекции + +Формат ввода команд: +- Все аргументы команды, являющиеся стандартными типами данных (примитивные типы, классы-оболочки, String, классы для хранения дат), должны вводиться в той же строке, что и имя команды. +- Все составные типы данных (объекты классов, хранящиеся в коллекции) должны вводиться по одному полю в строку. +- При вводе составных типов данных пользователю должно показываться приглашение к вводу, содержащее имя поля (например, "Введите дату рождения:") +- Если поле является enum'ом, то вводится имя одной из его констант (при этом список констант должен быть предварительно выведен). +- При некорректном пользовательском вводе (введена строка, не являющаяся именем константы в enum'е; введена строка вместо числа; введённое число не входит в указанные границы и т.п.) должно быть показано сообщение об ошибке и предложено повторить ввод поля. +- Для ввода значений null использовать пустую строку. +- Поля с комментарием "Значение этого поля должно генерироваться автоматически" не должны вводиться пользователем вручную при добавлении. + +Описание хранимых в коллекции классов: + +```java +public class Product { + private Long id; //Поле не может быть null, Значение поля должно быть больше 0, Значение этого поля должно быть уникальным, Значение этого поля должно генерироваться автоматически + private String name; //Поле не может быть null, Строка не может быть пустой + private Coordinates coordinates; //Поле не может быть null + private java.time.ZonedDateTime creationDate; //Поле не может быть null, Значение этого поля должно генерироваться автоматически + private Long price; //Поле не может быть null, Значение поля должно быть больше 0 + private String partNumber; //Длина строки не должна быть больше 82, Значение этого поля должно быть уникальным, Строка не может быть пустой, Поле может быть null + private long manufactureCost; + private UnitOfMeasure unitOfMeasure; //Поле не может быть null + private Person owner; //Поле не может быть null +} + +public class Coordinates { + private long x; //Максимальное значение поля: 883 + private Long y; //Значение поля должно быть больше -427, Поле не может быть null +} + +public class Person { + private String name; //Поле не может быть null, Строка не может быть пустой + private String passportID; //Длина строки должна быть не меньше 5, Длина строки не должна быть больше 22, Поле не может быть null + private Color hairColor; //Поле может быть null + private Location location; //Поле может быть null +} + +public class Location { + private float x; + private Integer y; //Поле не может быть null + private String name; //Строка не может быть пустой, Поле может быть null +} + +public enum UnitOfMeasure { + KILOGRAMS, + CENTIMETERS, + GRAMS +} + +public enum Color { + GREEN, + BLACK, + BLUE, + ORANGE, + WHITE +} +``` diff --git a/db.xml b/db.xml new file mode 100644 index 0000000..3885e88 --- /dev/null +++ b/db.xml @@ -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/pom.xml b/pom.xml new file mode 100644 index 0000000..8a16eac --- /dev/null +++ b/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + + me.zinch + Lab5 + 1.0 + jar + + Lab5 + + + UTF-8 + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.15.0 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.17.0 + + + org.hibernate.validator + hibernate-validator + 8.0.1.Final + + + org.glassfish + jakarta.el + 5.0.0-M1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + + + + + diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 962de4e..0000000 --- a/src/Main.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file diff --git a/src/main/java/me/zinch/App.java b/src/main/java/me/zinch/App.java new file mode 100644 index 0000000..ffc7edb --- /dev/null +++ b/src/main/java/me/zinch/App.java @@ -0,0 +1,18 @@ +package me.zinch; + +import me.zinch.files.DbController; +import me.zinch.models.Product; +import me.zinch.validator.Validators; + +import java.util.List; + +public class App { + public static void main( String[] args ) { + List productList = DbController.loadDb(); + if (productList != null) { + System.out.println(Validators.validateProductList(productList)); + } else { + System.exit(1); + } + } +} diff --git a/src/main/java/me/zinch/commands/Command.java b/src/main/java/me/zinch/commands/Command.java new file mode 100644 index 0000000..3cfbb80 --- /dev/null +++ b/src/main/java/me/zinch/commands/Command.java @@ -0,0 +1,29 @@ +package me.zinch.commands; + +public abstract class Command { + private final String name; + private final String description; + private final String pattern; + + public Command(String name, String description, String pattern) { + this.name = name; + this.description = description; + this.pattern = pattern; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getPattern() { + return this.pattern; + } + + public abstract void action(); + public abstract void action(String param); + public abstract void action(String[] params); +} diff --git a/src/main/java/me/zinch/files/DbController.java b/src/main/java/me/zinch/files/DbController.java new file mode 100644 index 0000000..3990224 --- /dev/null +++ b/src/main/java/me/zinch/files/DbController.java @@ -0,0 +1,41 @@ +package me.zinch.files; + +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.models.Product; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class DbController { + public static class Products { + @JacksonXmlElementWrapper(useWrapping = false) + @JacksonXmlProperty(localName = "Product") + private List products; + + public List getProducts() { + return products; + } + } + + public static List loadDb() { + Map env = System.getenv(); + try { + BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(env.getOrDefault("DB_FILE", ""))); + XmlMapper xmlMapper = XmlMapper.builder().addModule(new JavaTimeModule()).build(); + Products collection = xmlMapper.readValue(bufferedInputStream, Products.class); + return collection.getProducts(); + } catch (FileNotFoundException e) { + System.err.println("Ошибка! Файл не найден."); + } catch (IOException e) { + System.err.println("Произошла неожиданная ошибка во время работы с файлом!"); + } + return null; + } +} diff --git a/src/main/java/me/zinch/models/Color.java b/src/main/java/me/zinch/models/Color.java new file mode 100644 index 0000000..883b36e --- /dev/null +++ b/src/main/java/me/zinch/models/Color.java @@ -0,0 +1,9 @@ +package me.zinch.models; + +public enum Color { + GREEN, + BLACK, + BLUE, + ORANGE, + WHITE +} diff --git a/src/main/java/me/zinch/models/Coordinates.java b/src/main/java/me/zinch/models/Coordinates.java new file mode 100644 index 0000000..e04f04c --- /dev/null +++ b/src/main/java/me/zinch/models/Coordinates.java @@ -0,0 +1,40 @@ +package me.zinch.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; + +import java.util.Objects; + +public class Coordinates { + @Max(value = 883, message = "Максимальное значение поля x: 883") + @JsonProperty("x") + private long x; //Максимальное значение поля: 883 + + @NotNull(message = "Поле не может быть null") + @Min(value = -427, message = "Значение поля y должно быть больше -427") + @JsonProperty("y") + private Long y; //Значение поля должно быть больше -427, Поле не может быть null + + @Override + public String toString() { + return "Coordinates{" + + "x=" + x + + ", y=" + y + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Coordinates that = (Coordinates) o; + return x == that.x && Objects.equals(y, that.y); + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } +} diff --git a/src/main/java/me/zinch/models/Location.java b/src/main/java/me/zinch/models/Location.java new file mode 100644 index 0000000..2b8bb4d --- /dev/null +++ b/src/main/java/me/zinch/models/Location.java @@ -0,0 +1,54 @@ +package me.zinch.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.util.Objects; + +public class Location { + @JsonProperty("x") + private float x; + + @NotNull(message = "Поле y не может быть null") + @JsonProperty("y") + private Integer y; //Поле не может быть null + + @NotBlank(message = "Строка name не может быть пустой или null") + @JsonProperty("name") + private String name; //Строка не может быть пустой, Поле может быть null + + public float getX() { + return x; + } + + public Integer getY() { + return y; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Location{" + + "x=" + x + + ", y=" + y + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Location location = (Location) o; + return Float.compare(x, location.x) == 0 && Objects.equals(y, location.y) && Objects.equals(name, location.name); + } + + @Override + public int hashCode() { + return Objects.hash(x, y, name); + } +} diff --git a/src/main/java/me/zinch/models/Person.java b/src/main/java/me/zinch/models/Person.java new file mode 100644 index 0000000..0341f6f --- /dev/null +++ b/src/main/java/me/zinch/models/Person.java @@ -0,0 +1,50 @@ +package me.zinch.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.util.Objects; + +public class Person { + @NotBlank(message = "Строка name не может быть пустой или null") + @JsonProperty("name") + private String name; //Поле не может быть null, Строка не может быть пустой + + @NotNull(message = "Поле 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 + + @Override + public String toString() { + return "Person{" + + "name='" + name + '\'' + + ", passportID='" + passportID + '\'' + + ", hairColor=" + hairColor + + ", location=" + location + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Person person = (Person) o; + return Objects.equals(name, person.name) && Objects.equals(passportID, person.passportID) && hairColor == person.hairColor && Objects.equals(location, person.location); + } + + @Override + public int hashCode() { + return Objects.hash(name, passportID, hairColor, location); + } +} diff --git a/src/main/java/me/zinch/models/Product.java b/src/main/java/me/zinch/models/Product.java new file mode 100644 index 0000000..60108bb --- /dev/null +++ b/src/main/java/me/zinch/models/Product.java @@ -0,0 +1,137 @@ +package me.zinch.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import me.zinch.validator.NotEmpty; + +import java.time.ZonedDateTime; +import java.util.Objects; + +public class Product { + @NotNull(message = "Поле id не может быть null") + @Min(value = 1, message = "Значение поля id должно быть больше 0") + @JsonProperty("id") + private Long id; //Поле не может быть null, Значение поля должно быть больше 0, Значение этого поля должно быть уникальным, Значение этого поля должно генерироваться автоматически + + @NotBlank(message = "Строка name не может быть пустой или null") + @JsonProperty("name") + private String name; //Поле не может быть null, Строка не может быть пустой + + @NotNull(message = "Поле coordinates не может быть null ") + @JsonProperty("coordinates") + private Coordinates coordinates; //Поле не может быть null + + @NotNull(message = "Поле creationDate не может быть null") + @JsonProperty("creationDate") + private ZonedDateTime creationDate; //Поле не может быть null, Значение этого поля должно генерироваться автоматически + + @NotNull(message = "Поле price не может быть null") + @Min(value = 1, message = "Поле price не может быть null") + @JsonProperty("price") + private Long price; //Поле не может быть null, Значение поля должно быть больше 0 + + @NotEmpty(message = "Строка partNumber не может быть пустой") + @Size(max = 82, message = "Длина строки partNumber не должна быть больше 82") + @JsonProperty("partNumber") + private String partNumber; //Длина строки не должна быть больше 82, Значение этого поля должно быть уникальным, Строка не может быть пустой, Поле может быть null + + @JsonProperty("manufactureCost") + private long manufactureCost; + + @NotNull(message = "Поле unitOfMeasure не может быть null") + @JsonProperty("unitOfMeasure") + private UnitOfMeasure unitOfMeasure; //Поле не может быть null + + @NotNull(message = "Поле owner не может быть null") + @JsonProperty("owner") + private Person owner; //Поле не может быть null + + public Product() {} + + public Product (Long id, + String name, + Coordinates coordinates, + Long price, + String partNumber, + long manufactureCost, + UnitOfMeasure unitOfMeasure, + Person owner + ) { + this.id = id; + this.name = name; + this.coordinates = coordinates; + this.creationDate = ZonedDateTime.now(); + this.price = price; + this.partNumber = partNumber; + this.manufactureCost = manufactureCost; + this.unitOfMeasure = unitOfMeasure; + this.owner = owner; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public Coordinates getCoordinates() { + return coordinates; + } + + public ZonedDateTime getCreationDate() { + return creationDate; + } + + public Long getPrice() { + return price; + } + + public String getPartNumber() { + return partNumber; + } + + public long getManufactureCost() { + return manufactureCost; + } + + public UnitOfMeasure getUnitOfMeasure() { + return unitOfMeasure; + } + + public Person getOwner() { + return owner; + } + + @Override + public String toString() { + return "Product{" + + "id=" + id + + ", name='" + name + '\'' + + ", coordinates=" + coordinates + + ", creationDate=" + creationDate + + ", price=" + price + + ", partNumber='" + partNumber + '\'' + + ", manufactureCost=" + manufactureCost + + ", unitOfMeasure=" + unitOfMeasure + + ", owner=" + owner + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return manufactureCost == product.manufactureCost && Objects.equals(id, product.id) && Objects.equals(name, product.name) && Objects.equals(coordinates, product.coordinates) && Objects.equals(creationDate, product.creationDate) && Objects.equals(price, product.price) && Objects.equals(partNumber, product.partNumber) && unitOfMeasure == product.unitOfMeasure && Objects.equals(owner, product.owner); + } + + @Override + public int hashCode() { + return Objects.hash(id, name, coordinates, creationDate, price, partNumber, manufactureCost, unitOfMeasure, owner); + } +} diff --git a/src/main/java/me/zinch/models/UnitOfMeasure.java b/src/main/java/me/zinch/models/UnitOfMeasure.java new file mode 100644 index 0000000..18073b1 --- /dev/null +++ b/src/main/java/me/zinch/models/UnitOfMeasure.java @@ -0,0 +1,7 @@ +package me.zinch.models; + +public enum UnitOfMeasure { + KILOGRAMS, + CENTIMETERS, + GRAMS +} diff --git a/src/main/java/me/zinch/validator/NotEmpty.java b/src/main/java/me/zinch/validator/NotEmpty.java new file mode 100644 index 0000000..04bbb2a --- /dev/null +++ b/src/main/java/me/zinch/validator/NotEmpty.java @@ -0,0 +1,18 @@ +package me.zinch.validator; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = NotEmptyValidator.class) +public @interface NotEmpty { + String message() default "Value must not be blank"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/src/main/java/me/zinch/validator/NotEmptyValidator.java b/src/main/java/me/zinch/validator/NotEmptyValidator.java new file mode 100644 index 0000000..21d22b2 --- /dev/null +++ b/src/main/java/me/zinch/validator/NotEmptyValidator.java @@ -0,0 +1,11 @@ +package me.zinch.validator; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +public class NotEmptyValidator implements ConstraintValidator { + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + return value == null || !value.trim().isEmpty(); + } +} \ No newline at end of file diff --git a/src/main/java/me/zinch/validator/Validators.java b/src/main/java/me/zinch/validator/Validators.java new file mode 100644 index 0000000..01b2f26 --- /dev/null +++ b/src/main/java/me/zinch/validator/Validators.java @@ -0,0 +1,36 @@ +package me.zinch.validator; + +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +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; + + static { + ValidatorFactory factory = Validation.byProvider(HibernateValidator.class) + .configure() + .showValidatedValuesInTraceLogs(false) + .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 boolean validateProductList(List db) { + return db.stream().allMatch(Validators::validateProduct); + } +}