diff --git a/alo.xml b/alo.xml new file mode 100644 index 0000000..4d83f58 --- /dev/null +++ b/alo.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/main/java/me/zinch/commands/Exit.java b/src/main/java/me/zinch/commands/Exit.java index 679cf6a..a965e37 100644 --- a/src/main/java/me/zinch/commands/Exit.java +++ b/src/main/java/me/zinch/commands/Exit.java @@ -13,7 +13,7 @@ public class Exit extends Command { @Override public String action(ProductCollection productCollection) { - Console.stopApp(); + Console.stopAppWithoutSaving(); return ""; } } diff --git a/src/main/java/me/zinch/console/Console.java b/src/main/java/me/zinch/console/Console.java index 18c6df0..999c3ac 100644 --- a/src/main/java/me/zinch/console/Console.java +++ b/src/main/java/me/zinch/console/Console.java @@ -10,6 +10,7 @@ import me.zinch.models.Color; import me.zinch.models.Coordinates; import me.zinch.models.Location; import me.zinch.models.Person; +import me.zinch.models.Product; import me.zinch.models.ProductDTO; import me.zinch.models.UnitOfMeasure; import me.zinch.validator.ValidateResult; @@ -20,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Scanner; /** @@ -32,17 +34,36 @@ public class Console { private static final List history = new ArrayList<>(); private static boolean isExitMessageShowed = false; + private static ProductCollection productCollection; + public static void appendHistory(String input) { history.add(input); } - public static void stopApp() { - isRunning = false; - ShowExitMessage(); + public static void log(String msg) { + if (isRunning) System.out.println(msg); } - public static void ShowExitMessage() { - if (!isExitMessageShowed) System.out.println("Всего хорошего!"); + public static void log() { + log(""); + } + + public static void stopAppWithoutSaving() { + showExitMessage(); + isRunning = false; + } + + public static void stopAppWithSaving() { + try { + DbController.saveDb(productCollection.toList()); + } catch (IOException e) { + log(e.getMessage()); + } + stopAppWithoutSaving(); + } + + public static void showExitMessage() { + if (!isExitMessageShowed) log("\nВсего хорошего!"); isExitMessageShowed = true; } @@ -52,13 +73,14 @@ public class Console { private static String readString() { + if (!scanner.hasNextLine()) Console.stopAppWithSaving(); var input = scanner.nextLine().trim(); return input.isEmpty() ? null : input; } private static Long readLong() { - var input = scanner.nextLine().trim(); - if (input.isEmpty()) return null; + var input = readString(); + if (input == null || input.isEmpty()) return null; try { return Long.parseLong(input); } catch (NumberFormatException e) { @@ -108,14 +130,28 @@ public class Console { return new Location(locationX, locationY, locationName); } + private static String readPartNumber() throws IllegalArgumentException { + var partNumber = readString(); + var partNumbers = productCollection.toList() + .stream() + .map(Product::getPartNumber) + .filter(Objects::nonNull) + .filter(s -> s.equals(partNumber)) + .toList(); + if (!partNumbers.isEmpty()) { + throw new IllegalArgumentException("Поле partNumber должно быть уникальным"); + } + return partNumber; + } + private static void readField(String fieldName, Runnable function) { - while (true) { + while (isRunning) { if (fieldName != null) System.out.format("%s: ", fieldName); try { function.run(); return; } catch (NullPointerException e) { - System.out.println("Произошла ошибка при заполнении поля\nПоле не может быть null"); + log("Произошла ошибка при заполнении поля\nПоле не может быть пустым"); } catch (Exception e) { System.out.format("Произошла ошибка при заполнении поля%n%s%n", e.getMessage()); } @@ -130,17 +166,17 @@ public class Console { var productDTO = new ProductDTO(); var coordinates = new Coordinates(); var owner = new Person(); - System.out.println("Заполните следующие поля: "); + log("Заполните следующие поля: "); - readField("Название", () -> productDTO.setName(readString())); - readField("Координата x", () -> coordinates.setX(readLong())); - readField("Координата y", () -> coordinates.setY(readLong())); - readField("Цена", () -> productDTO.setPrice(readLong())); - readField("Номер части", () -> productDTO.setPartNumber(readString())); - readField("Себестоимость", () -> productDTO.setManufactureCost(readLong())); + readField("Название [не может быть пустым]", () -> productDTO.setName(readString())); + readField("Координата x [должна быть меньше 884]", () -> coordinates.setX(readLong())); + readField("Координата y [должна быть больше -427, не может быть пустой]", () -> coordinates.setY(readLong())); + readField("Цена [должна быть больше 0, не может быть пустой]", () -> productDTO.setPrice(readLong())); + readField("Номер части [не больше 82 символов, должен быть уникальным]", () -> productDTO.setPartNumber(readPartNumber())); + readField("Себестоимость [не может быть пустым]", () -> productDTO.setManufactureCost(readLong())); readField(() -> productDTO.setUnitOfMeasure(readUnitOfMeasure())); - readField("Имя владельца", () -> owner.setName(readString())); - readField("Данные паспорта", () -> owner.setPassportID(readString())); + readField("Имя владельца [не может быть пустым]", () -> owner.setName(readString())); + readField("Данные паспорта [длина строки от 5 до 22, не может быть пустым]", () -> owner.setPassportID(readString())); readField(() -> owner.setHairColor(readColor())); readField(() -> owner.setLocation(readLocation())); @@ -152,6 +188,7 @@ public class Console { public static void run() throws IOException, ValidationException { var productList = DbController.loadDb(); var validationResult = Validators.validateProductList(productList); + if (!validationResult.stream().allMatch(ValidateResult::isValid)) { throw new ValidationException(String.join("\n", validationResult .stream() @@ -159,27 +196,33 @@ public class Console { .toList())); } - var productCollection = new ProductCollection(productList); - System.out.println("Добро пожаловать! Для просмотра команд введите help"); + if (productList.isEmpty()) log("Коллекция путая\n"); + + productCollection = new ProductCollection(productList); + log("Добро пожаловать! Для просмотра команд введите help"); + while(isRunning) { System.out.print(":"); + try { var input = scanner.nextLine().trim(); var command = CommandManager.getCommandByInput(input); + if (command.isPresent()) { appendHistory(input); + try { - System.out.println(command.get().action(productCollection)); + log(command.get().action(productCollection)); } catch (CommandActionException e) { - System.out.println(e.getMessage()); + log(e.getMessage()); } } else { - System.out.println("Такой команды не существует. Напишите help, чтобы посмотреть список доступных команд."); + log("Такой команды не существует. Напишите help, чтобы посмотреть список доступных команд."); } } catch (NoSuchElementException e) { - stopApp(); + stopAppWithoutSaving(); } - System.out.println(); + log(); } scanner.close(); } diff --git a/src/main/java/me/zinch/console/ShutdownHook.java b/src/main/java/me/zinch/console/ShutdownHook.java index 4f86ad0..0d51455 100644 --- a/src/main/java/me/zinch/console/ShutdownHook.java +++ b/src/main/java/me/zinch/console/ShutdownHook.java @@ -5,6 +5,6 @@ package me.zinch.console; */ public class ShutdownHook extends Thread { public ShutdownHook() { - super(new Thread(Console::stopApp)); + super(new Thread(Console::stopAppWithSaving)); } } diff --git a/src/main/java/me/zinch/files/DbController.java b/src/main/java/me/zinch/files/DbController.java index 141648f..7e21f59 100644 --- a/src/main/java/me/zinch/files/DbController.java +++ b/src/main/java/me/zinch/files/DbController.java @@ -1,18 +1,14 @@ 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.exceptions.ValidationException; import me.zinch.models.Product; import java.io.BufferedInputStream; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; @@ -59,15 +55,8 @@ public class DbController { bufferedInputStream.close(); if (collection == null) return new ArrayList<>(); return collection; - } catch (FileNotFoundException e) { - throw new FileNotFoundException("Не удалось найти файл " + path); - } catch (DatabindException e) { - if (e.getCause() instanceof ValidationException) { - throw new DbInitializationException(String.format("Ошибка при валидации базы%n%s", e.getCause().getMessage())); - } - throw new DbInitializationException(); } catch (IOException e) { - throw new IOException("Произошла неожиданная ошибка во время работы с файлом!"); + return new ArrayList<>(); } } @@ -76,10 +65,8 @@ public class DbController { OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path)); xmlMapper.writeValue(outputStreamWriter, new Products(list)); outputStreamWriter.close(); - } catch (FileNotFoundException e) { - throw new FileNotFoundException(e.getMessage()); } catch (IOException e) { - throw new IOException(e); + throw new IOException("Не удалось записать в файл"); } } } diff --git a/src/main/java/me/zinch/validator/Validators.java b/src/main/java/me/zinch/validator/Validators.java index beb3a10..e992e09 100644 --- a/src/main/java/me/zinch/validator/Validators.java +++ b/src/main/java/me/zinch/validator/Validators.java @@ -36,7 +36,6 @@ public class Validators { if (ids.size() != Set.copyOf(ids).size()) { validations.add(new ValidateResult<>("Поле id должно быть уникальным")); } - var a = Set.copyOf(partNumbers); if (partNumbers.size() != Set.copyOf(partNumbers).size()) { validations.add(new ValidateResult<>("Поле partNumbers должно быть уникальным")); } diff --git a/src/main/java/me/zinch/wrapper/ProductCollection.java b/src/main/java/me/zinch/wrapper/ProductCollection.java index f3bfa6b..834239b 100644 --- a/src/main/java/me/zinch/wrapper/ProductCollection.java +++ b/src/main/java/me/zinch/wrapper/ProductCollection.java @@ -24,7 +24,7 @@ public class ProductCollection { public ProductCollection(List list) throws ValidationException { productList = new TreeSet<>(Comparator.comparingLong(Product::getId)); productList.addAll(list); - idIncrementor = productList.isEmpty() ? 0L : productList.last().getId() + 1; + idIncrementor = productList.isEmpty() ? 1L : productList.last().getId() + 1; } private Long generateId() {