diff --git a/auxiliary/Script b/auxiliary/Script new file mode 100644 index 0000000..345b22c --- /dev/null +++ b/auxiliary/Script @@ -0,0 +1,26 @@ +add +cat +nyan-cat +5 +12 +True +True +4 +5.123 +sadness +McQueen +True +update +1 +dog +piesek +2 +15 +True +False +4 +6.22 +longing +BrokeCar +False +remove_by_id 1 \ No newline at end of file diff --git a/src/auxiliary/Structure b/auxiliary/Structure similarity index 96% rename from src/auxiliary/Structure rename to auxiliary/Structure index 6c9b89e..5201bdf 100644 --- a/src/auxiliary/Structure +++ b/auxiliary/Structure @@ -22,8 +22,8 @@ handlers: FileInputHandler - производит считывание из файла. Наследуется от InputHandler. InputHandler - абстрактный класс, хранящий в себе большую часть функционала для дочерних классов. -human_being - папка, хранящая в себе класс элементов коллекции. -human_being: +source - папка, хранящая в себе класс элементов коллекции. +source: Car - мини-класс, используемый в поле класса HumanBeing. Coordinates - мини-класс, используемый в поле класса HumanBeing. HumanBeing - класс, описывающий элемент коллекции humanCollection. diff --git a/auxiliary/Tests b/auxiliary/Tests new file mode 100644 index 0000000..bfd4c81 --- /dev/null +++ b/auxiliary/Tests @@ -0,0 +1,79 @@ +Формат ввода команд: +COMMAND + + + + + + //может быть null + + //может быть null + //может быть null + + +Тест 1: +add +cat +nyan-cat +5 +12 +True +True +4 +5.123 +sadness +McQueen +True + +Тест 2: +update +1 +dog +piesek +2 +15 +True +False +4 +6.22 +longing +BrokeCar +False + +Тест 3: +add +cat +nyan-cat +5 +12 +True +True +4 +5.123 +sadness +McQueen +True + +Тест 4: +add +cat ffkg dflkdf dflkvmf +nyan-cat +5 ffff fffff fffffff +12 55555 44444 3333 +True fvmdv +True vfkdmkmvffdfvfdvfdvdvdvfdvd +4 5.123 kdk mkmfkmdfmdm +sadness d iodjvodmvkmdmvk +McQueen True kvd + +Тест 5: +add rfrjtnj ufdyj c.lf ddtle ,e,e,e,e,e +cat ffkg dflkdf dflkvmf +nyan-cat +5 ffff fffff fffffff +12 55555 44444 3333 +True fvmdv +True vfkdmkmvffdfvfdvfdvdvdvfdvd +4 5.123 kdk mkmfkmdfmdm +sadness d iodjvodmvkmdmvk +McQueen True kvd \ No newline at end of file diff --git a/src/auxiliary/Tests b/src/auxiliary/Tests deleted file mode 100644 index 34886ce..0000000 --- a/src/auxiliary/Tests +++ /dev/null @@ -1,18 +0,0 @@ -Формат ввода команд: -COMMAND - - - - -Тест 1: -add cat nyan-cat 5 12 True True -4 5.123 -sadness -McQueen True - -Тест 2: -update 1 -dog piesek 2 15 True False -4 6.22 -longing -BrokeCar False \ No newline at end of file diff --git a/src/commands/AddCommand.java b/src/commands/AddCommand.java index 43bdc0b..7099ba8 100644 --- a/src/commands/AddCommand.java +++ b/src/commands/AddCommand.java @@ -1,30 +1,29 @@ package commands; -import dao.ArrayDequeDAO; -import human_being.HumanBeing; +import dao.DAO; +import handlers.InputHandler; import service.FormedManager; +import source.HumanBeing; /** - * ЗДЕСЬ БУДЕТ ПОЛНАЯ ОБРАБОТКА ВХОДНЫХ ДАННЫХ С ФОРМИРОВАНИЕМ ЭЛЕМЕНТОВ + * Класс команды add. Добавляет новый элемент в коллекцию. */ public class AddCommand implements Command { - private final ArrayDequeDAO arrayDequeDAO; + private final DAO arrayDequeDAO; + private final FormedManager manager = new FormedManager(); - public AddCommand(ArrayDequeDAO arrayDequeDAO) { + public AddCommand(DAO arrayDequeDAO) { this.arrayDequeDAO = arrayDequeDAO; } /** * Обработка поступивших паратемтров и добавление их в коллекцию - * @param arguments - все аргументы, нужные для формирования аргумента, в виде строки + * @param reader - экземпляр класса InputHandler который определяет тип считывания */ @Override - public void execute(String arguments) { - // Создаю экземпляр класса формирователя - FormedManager manager = new FormedManager(); - // Новый экземпляр класса human_being.HumanBeing - HumanBeing newHuman = manager.formed(arguments); - // Добавление экземпляра класса в коллекцию - arrayDequeDAO.add(newHuman); + public void execute(InputHandler reader) { + HumanBeing existedHuman = manager.formed(reader); + arrayDequeDAO.add(existedHuman); + System.out.print("add: Ура Ура! Элемент добавлен в коллекцию!\n"); } } diff --git a/src/commands/ClearCommand.java b/src/commands/ClearCommand.java new file mode 100644 index 0000000..9417ca9 --- /dev/null +++ b/src/commands/ClearCommand.java @@ -0,0 +1,30 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; + +/** + * Класс команды clear + * Очищает коллекцию + */ +public class ClearCommand implements Command{ + private final DAO arrayDequeDAO; + + public ClearCommand(DAO arrayDequeDAO){ + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + if (arrayDequeDAO.size() != 0) { + for (int i=0; i < arrayDequeDAO.getAvailableId(); i++){ + if (arrayDequeDAO.get(i) != null){ + arrayDequeDAO.remove(i); + } + } + System.out.print("clear: Коллекция успешно очищена.\n"); + } else { + System.err.print("clear: Коллекция и так пуста.\n"); + } + } +} diff --git a/src/commands/Command.java b/src/commands/Command.java index b87524e..47b13e2 100644 --- a/src/commands/Command.java +++ b/src/commands/Command.java @@ -1,5 +1,7 @@ package commands; +import handlers.InputHandler; + public interface Command { - void execute(String arguments); + void execute(InputHandler reader); } diff --git a/src/commands/DeleteCommand.java b/src/commands/DeleteCommand.java deleted file mode 100644 index f385ec9..0000000 --- a/src/commands/DeleteCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package commands; - -import dao.ArrayDequeDAO; - -public class DeleteCommand implements Command { - ArrayDequeDAO arrayDequeDAO; - - public DeleteCommand(ArrayDequeDAO arrayDequeDAO) { - this.arrayDequeDAO = arrayDequeDAO; - } - - @Override - public void execute(String arguments) { - // если элемент есть то все ок - arrayDequeDAO.delete(); - } - -} diff --git a/src/commands/HeadCommand.java b/src/commands/HeadCommand.java new file mode 100644 index 0000000..84e6c93 --- /dev/null +++ b/src/commands/HeadCommand.java @@ -0,0 +1,26 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; + + +/** + * Класс команды head + * Выводит первый элемент коллекции + */ +public class HeadCommand implements Command{ + private final DAO arrayDequeDAO; + + public HeadCommand(DAO arrayDequeDAO){ + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + if (arrayDequeDAO.size() != 0) { + System.out.print("head: " + arrayDequeDAO.show() +"\n"); + } else { + System.err.print("head: Sorry, коллекция пуста.\n"); + } + } +} diff --git a/src/commands/HelpCommand.java b/src/commands/HelpCommand.java new file mode 100644 index 0000000..3a1c364 --- /dev/null +++ b/src/commands/HelpCommand.java @@ -0,0 +1,31 @@ +package commands; + +import handlers.InputHandler; + +/** + * Класс команды help + * Выводит справку по доступным командам + */ +public class HelpCommand implements Command{ + + @Override + public void execute(InputHandler reader) { + System.out.print("Доступные команды: \n" + + "help - вывести справку по доступным командам \n" + + "info - вывести в стандартный поток вывода информацию о коллекции (тип, дата инициализации, количество элементов и т.д.) \n" + + "show - вывести в стандартный поток вывода все элементы коллекции в строковом представлении \n" + + "add {element} - добавить новый элемент в коллекцию \n" + + "update id {element} - обновить значение элемента коллекции, id которого равен заданному \n" + + "remove_by_id id - удалить элемент из коллекции по его id \n" + + "clear - очистить коллекцию \n" + + "save - сохранить коллекцию в файл \n" + + "execute_script file_name - считать и исполнить скрипт из указанного файла \n" + + "exit - завершить программу (без сохранения в файл) \n" + + "head - вывести первый элемент коллекции \n" + + "remove_head - вывести первый элемент коллекции и удалить его \n" + + "remove_greater {element} - удалить из коллекции все элементы, превышающие заданный \n" + + "filter_by_minutes_of_waiting minutesOfWaiting - вывести элементы, значение поля minutesOfWaiting которых равно заданному \n" + + "filter_greater_than_impact_speed impactSpeed - вывести элементы, значение поля impactSpeed которых больше заданного \n" + + "print_unique_impact_speed - вывести уникальные значения поля impactSpeed всех элементов в коллекции \n"); + } +} diff --git a/src/commands/InfoCommand.java b/src/commands/InfoCommand.java new file mode 100644 index 0000000..9e77107 --- /dev/null +++ b/src/commands/InfoCommand.java @@ -0,0 +1,21 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; + +/** + * Класс команды info + * Вывести в стандартный поток вывода информацию о коллекции (тип, дата инициализации, количество элементов и т.д.) + */ +public class InfoCommand implements Command { + private final DAO arrayDequeDAO; + + public InfoCommand(DAO arrayDequeDAO){ + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + System.out.print("info: Коллекция ArrayDeque, создана: " + "..." + "\n" + "Количество элементов: " + arrayDequeDAO.size() + "\n"); + } +} diff --git a/src/commands/ReadCommand.java b/src/commands/ReadCommand.java index d9c9ec8..1f6997e 100644 --- a/src/commands/ReadCommand.java +++ b/src/commands/ReadCommand.java @@ -1,17 +1,25 @@ package commands; import dao.ArrayDequeDAO; +import dao.DAO; +import handlers.InputHandler; +import java.util.ArrayList; + +/** + * Класс команды help + * Выводит первый элемент коллекции + */ public class ReadCommand implements Command { - ArrayDequeDAO arrayDequeDAO; + private final DAO arrayDequeDAO; - public ReadCommand(ArrayDequeDAO arrayDequeDAO) { + public ReadCommand(DAO arrayDequeDAO) { this.arrayDequeDAO = arrayDequeDAO; } @Override - public void execute(String arguments) { + public void execute(InputHandler reader) { // если айдишка есть то все ок - arrayDequeDAO.read(); + //arrayDequeDAO.read(); } } diff --git a/src/commands/RemoveCommand.java b/src/commands/RemoveCommand.java new file mode 100644 index 0000000..8f2c1b4 --- /dev/null +++ b/src/commands/RemoveCommand.java @@ -0,0 +1,28 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; +import service.AskInput; + +/** + * Класс команды remove_by_id + * Удаляет элемент из коллекции по его id + */ +public class RemoveCommand implements Command { + private final DAO arrayDequeDAO; + + public RemoveCommand(DAO arrayDequeDAO) { + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + int id = AskInput.askId(reader); + if(arrayDequeDAO.get(id) != null) { + arrayDequeDAO.remove(id); + System.out.print("remove_by_id: Эхб, элемент удалили....\n"); + } else { + System.err.print("remove_by_id: Элемента с таким id не нашлось.\n"); + } + } +} diff --git a/src/commands/RemoveHeadCommand.java b/src/commands/RemoveHeadCommand.java new file mode 100644 index 0000000..d714474 --- /dev/null +++ b/src/commands/RemoveHeadCommand.java @@ -0,0 +1,26 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; + +/** + * Класс команды help + * Выводит первый элемент коллекции и удалить его + */ +public class RemoveHeadCommand implements Command{ + private final DAO arrayDequeDAO; + + public RemoveHeadCommand(DAO arrayDequeDAO){ + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + if (arrayDequeDAO.size() != 0) { + System.out.print("remove_head: элемент " + arrayDequeDAO.show() + " успешно удалён!\n"); + arrayDequeDAO.remove(arrayDequeDAO.show().getId()); + } else { + System.err.print("remove_head: Sorry, коллекция пуста.\n"); + } + } +} diff --git a/src/commands/ScriptCommand.java b/src/commands/ScriptCommand.java new file mode 100644 index 0000000..6127b2c --- /dev/null +++ b/src/commands/ScriptCommand.java @@ -0,0 +1,25 @@ +package commands; + +import handlers.InputHandler; +import service.AskInput; +import service.CommandManager; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; + +/** + * Класс команды execute_script file_name + * Считывает и исполняет скрипт из указанного файла + */ +public class ScriptCommand implements Command{ + private final AskInput request = new AskInput(); + + @Override + public void execute(InputHandler reader) { + // считываем имя файла + FileInputStream usableFile = request.askFileName(reader); + BufferedInputStream bufferedInput = new BufferedInputStream(usableFile); + // меняем тип считывания на файловый + CommandManager.turnOnFile(bufferedInput); + } +} diff --git a/src/commands/ShowCommand.java b/src/commands/ShowCommand.java new file mode 100644 index 0000000..60155b1 --- /dev/null +++ b/src/commands/ShowCommand.java @@ -0,0 +1,30 @@ +package commands; + +import dao.DAO; +import handlers.InputHandler; + +/** + * Класс команды show + * Выводит в стандартный поток вывода все элементы коллекции в строковом представлении + */ +public class ShowCommand implements Command{ + private final DAO arrayDequeDAO; + + public ShowCommand(DAO arrayDequeDAO){ + this.arrayDequeDAO = arrayDequeDAO; + } + + @Override + public void execute(InputHandler reader) { + if (arrayDequeDAO.size() == 0) { + System.err.print("show: Коллекция пустая!\n"); + } else { + System.out.print("show: \n"); + for (int i = 0; i < arrayDequeDAO.getAvailableId(); i++) { + if (arrayDequeDAO.get(i) != null) { + System.out.print(arrayDequeDAO.get(i).toString() + "\n"); + } + } + } + } +} diff --git a/src/commands/UpdateCommand.java b/src/commands/UpdateCommand.java index a034923..926d715 100644 --- a/src/commands/UpdateCommand.java +++ b/src/commands/UpdateCommand.java @@ -1,20 +1,32 @@ package commands; -import dao.ArrayDequeDAO; +import dao.DAO; +import handlers.InputHandler; +import service.AskInput; import service.FormedManager; +import source.HumanBeing; +/** + * Класс команды update id {element} + * Обновляет значение элемента коллекции, id которого равен заданному + */ public class UpdateCommand implements Command { - ArrayDequeDAO arrayDequeDAO; + private final DAO arrayDequeDAO; + private final FormedManager manager = new FormedManager(); - public UpdateCommand(ArrayDequeDAO arrayDequeDAO) { + public UpdateCommand(DAO arrayDequeDAO) { this.arrayDequeDAO = arrayDequeDAO; } @Override - public void execute(String arguments) { - int existedId = Integer.parseInt(arguments.substring(0, arguments.indexOf(" "))); - arguments = arguments.substring(arguments.indexOf(" ") + 1); - FormedManager manager = new FormedManager(); - arrayDequeDAO.update(existedId, manager.formed(arguments)); + public void execute(InputHandler reader) { + int id = AskInput.askId(reader); + if(arrayDequeDAO.get(id) != null) { + HumanBeing existedHuman = manager.formed(reader); + arrayDequeDAO.update(id, existedHuman); + System.out.print("update: Ура ура! Элемент обновлён!\n"); + } else { + System.err.print("update: Элемента с таким id не нашлось.\n"); + } } } diff --git a/src/dao/ArrayDequeDAO.java b/src/dao/ArrayDequeDAO.java index 1cbcc05..6407ff8 100644 --- a/src/dao/ArrayDequeDAO.java +++ b/src/dao/ArrayDequeDAO.java @@ -1,36 +1,26 @@ package dao; -import human_being.HumanBeing; -import service.GenerateID; +import source.HumanBeing; +import service.Generator; import java.util.ArrayDeque; +import java.util.Deque; -public class ArrayDequeDAO implements DAO { - /** - * ЗДЕСЬ ВСЕ БУДЕТ ПРОСТО ВЫПОЛНЯТЬСЯ БЕЗ ПРОВЕРОК ИЛИ ОБРАБОТКИ КАК ЭТО ЕСТЬ У ЕГОШИНА - */ +public final class ArrayDequeDAO implements DAO { private static int availableId = 1; - private final ArrayDeque humanCollection = new ArrayDeque<>(); - - public void update() { - System.out.print("Update..."); - } - public void read() { - System.out.print("Select..."); - } - public void delete() { - System.out.print("Delete..."); - } + private final Deque humanCollection = new ArrayDeque<>(); + private final Generator generator = new Generator(); /** - * Добавление нового элемента у коллекцию + * Добавление нового элемента в коллекцию * @param newHuman - новый элемент коллекции * @return - id нового элемента коллекции */ @Override public int add(HumanBeing newHuman) { humanCollection.add(newHuman); - new GenerateID(humanCollection, newHuman); + generator.generateID(newHuman); + generator.generateCreationDate(newHuman); return availableId++; } @@ -41,7 +31,7 @@ public int add(HumanBeing newHuman) { */ @Override public void update(int id, HumanBeing updatedHuman) { - HumanBeing existedHuman = get(updatedHuman.getId()); + HumanBeing existedHuman = get(id); if(existedHuman != null) { existedHuman.setName(updatedHuman.getName()); existedHuman.setSoundtrackName(updatedHuman.getSoundtrackName()); @@ -55,6 +45,14 @@ public void update(int id, HumanBeing updatedHuman) { } } + @Override + public void remove(int id) { + HumanBeing existedHuman = get(id); + if(existedHuman != null) { + humanCollection.remove(existedHuman); + } + } + /** * Нахождение элемента по id * @param id - айдишник нужного элемента @@ -69,4 +67,19 @@ public HumanBeing get(int id) { } return null; } + + @Override + public HumanBeing show() { + return humanCollection.peek(); + } + + @Override + public int size(){ + return humanCollection.size(); + } + + @Override + public int getAvailableId(){ + return availableId; + } } diff --git a/src/dao/DAO.java b/src/dao/DAO.java index af5ff90..bf80e63 100644 --- a/src/dao/DAO.java +++ b/src/dao/DAO.java @@ -1,11 +1,13 @@ package dao; -import human_being.HumanBeing; +import source.HumanBeing; public interface DAO { int add(HumanBeing human); void update(int id, HumanBeing human); -// void delete(int id); + void remove(int id); HumanBeing get(int id); -// Collection show(); + HumanBeing show(); + int size(); + int getAvailableId(); } diff --git a/src/handlers/ConsoleInputHandler.java b/src/handlers/ConsoleInputHandler.java index 8377997..553ff2a 100644 --- a/src/handlers/ConsoleInputHandler.java +++ b/src/handlers/ConsoleInputHandler.java @@ -3,18 +3,15 @@ import java.util.Scanner; public class ConsoleInputHandler extends InputHandler { + private final Scanner scanner = new Scanner(System.in); /** * Переопределённый метод для считывания с консоли * @return считанная строка без лишних пробелов - * @exception RuntimeException */ @Override - public String read() { - String input = new Scanner(System.in).nextLine(); - input = removeSpaces(input); - if(input.isEmpty()) { - throw new RuntimeException("Пустой ввод!"); - } + public String readInput() { + // ВНИМАНИЕ!!!! Считывает только первое слово введённой строки. Остальные данные игнорируются. + String input = scanner.nextLine().trim().split(" ")[0]; return input; } } diff --git a/src/handlers/FileInputHandler.java b/src/handlers/FileInputHandler.java index e3ce55e..a130e26 100644 --- a/src/handlers/FileInputHandler.java +++ b/src/handlers/FileInputHandler.java @@ -1,8 +1,33 @@ package handlers; +import java.io.*; + public class FileInputHandler extends InputHandler { + private final BufferedInputStream bufferedInput; + private String word = ""; + + public FileInputHandler(BufferedInputStream bufferedInput) { + this.bufferedInput = bufferedInput; + } + + /** + * Переопределённый метод для считывания с файла + * @return одно слово указанного файла + */ @Override - public String read() { - return null; + public String readInput() { + int i; + try { + i = bufferedInput.read(); + while(i != -1) { + if(i == ' ' || i == '\n') break; + word += (char)i; + i = bufferedInput.read(); + } + } catch (IOException e) { + System.err.print("Произошла ошибка.\n"); + return null; + } + return word; } } diff --git a/src/handlers/InputHandler.java b/src/handlers/InputHandler.java index 9768871..c0c8447 100644 --- a/src/handlers/InputHandler.java +++ b/src/handlers/InputHandler.java @@ -1,57 +1,11 @@ package handlers; +import java.io.IOException; + public abstract class InputHandler { /** * Абстрактный метод read, переопределяемый для двух разных типов считывания - с консоли и с файла */ - public abstract String read(); - /** - *Убирает лишние пробелы из полученной строки для дальнейшей обработки - * @param input - только что введённая строка - * @return - строка без лишних пробелов - */ - public String removeSpaces(String input) { - input = input.trim(); - while(input.contains(" ")) { - input = input.replace(" ", " "); - } - return input; - } - - // вырезаем первое слово из общей строки - public static String getFirstWord(String input) { - if(input.contains(" ")) { - return input.substring(0, input.indexOf(" ")); - } - return input; - } - - /** - * Считывает оставшиеся элементы - * @return - */ - public String readAnotherElement() { - System.out.print("Введите координаты:\n"); - String coord = read(); - System.out.print("Введите состояние персонажа:\n"); - String mood = read(); - System.out.print("Введите машину персонажа:\n"); - String car = read(); - return " " + coord + " " + mood + " " + car; - } - - /** - * Обрезка строки без первого слова для дальнейшей работы - * @param input - строка, подающаяся на вход - * @return обрезанная строка без первого слова - */ - public String getArguments(String input) { - return input.substring(input.indexOf(" ") + 1); - } - /** - * Определяет нужную команду, либо выбрасывает ошибку - * @param input - */ - + public abstract String readInput(); } diff --git a/src/human_being/Car.java b/src/human_being/Car.java deleted file mode 100644 index 5135ca4..0000000 --- a/src/human_being/Car.java +++ /dev/null @@ -1,26 +0,0 @@ -package human_being; - -public class Car implements Comparable { - private String name; //Поле может быть null - private boolean cool; - - public Car(String name, boolean cool){ - this.name = name; - this.cool = cool; - } - - Car(boolean cool){ - this.name = null; - this.cool = cool; - } - - @Override - public int compareTo(Object o) { - Car car = (Car) o; - int result = this.name.compareTo(car.name); - if (result == 0){ - result = Boolean.compare(this.cool, car.cool); - } - return result; - } -} diff --git a/src/others/DataBaseRunner.java b/src/others/DataBaseRunner.java index 21acdef..6df47e0 100644 --- a/src/others/DataBaseRunner.java +++ b/src/others/DataBaseRunner.java @@ -1,54 +1,21 @@ package others; -import commands.*; -import dao.ArrayDequeDAO; -import handlers.ConsoleInputHandler; -import handlers.InputHandler; +import service.AskInput; +import service.CommandManager; -import java.util.Objects; - -enum CommandType { - ADD("1"), - UPDATE("2"); - private String title; - - CommandType(String type) { - this.title = type; - } - - public String getTitle() { - return title; - } - -} -// TODO придумать что сделать с разными по параметрам командами public class DataBaseRunner { + /** + * Главный класс + * @param args + */ public static void main(String [] args) { - ArrayDequeDAO database = new ArrayDequeDAO(); - - Command[] commands = { - new AddCommand(database), - new UpdateCommand(database), - new ReadCommand(database), - new DeleteCommand(database) - }; - - InputHandler reader = new ConsoleInputHandler(); - String input = reader.read(); - String command = InputHandler.getFirstWord(input); - String arguments = reader.getArguments(input); - - int commandIndex = CommandType.valueOf(command.toUpperCase()).ordinal(); - String title = CommandType.valueOf(command.toUpperCase()).getTitle(); - if(Objects.equals(title, "1")) { - arguments += reader.readAnotherElement(); - } - else if(Objects.equals(title, "2")) { - arguments += " " + reader.read(); - arguments += reader.readAnotherElement(); - } - commands[commandIndex].execute(arguments); + // определяем нужен ли нам дружественный интерфейс + AskInput.turnOnFriendly(); + // считывать начинаем с консоли + CommandManager.turnOnConsole(); + // запускаем менеджер-определитель команды + CommandManager.start(); } } diff --git a/src/service/AskInput.java b/src/service/AskInput.java new file mode 100644 index 0000000..79e8171 --- /dev/null +++ b/src/service/AskInput.java @@ -0,0 +1,306 @@ +package service; + +import handlers.ConsoleInputHandler; +import handlers.InputHandler; +import source.Car; +import source.Coordinates; +import source.Mood; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +/** + * Класс, позволяющий переключать дружественный интерфейс для быстрой тестировки + * а также сразу обрабатывающий строку на наличие ошибок, связанных с типом данных + */ +public class AskInput { + private static boolean friendlyInterface; + + /** + * Метод, позволяющй включить дружественный интерфейс + * @throws RuntimeException + */ + public static void turnOnFriendly() throws RuntimeException { + InputHandler inputHandler = new ConsoleInputHandler(); + System.out.println("Включить дружественный интерфейс?"); + String input = inputHandler.readInput().toLowerCase(); + try { + friendlyInterface = getBooleanInput(input); + } catch(NumberFormatException e) { + System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + turnOnFriendly(); + } catch (IllegalArgumentException e) { + System.err.print("Программа не понимает вашего ответа. Повторите попытку.\n"); + turnOnFriendly(); + } + } + + /** + * Метод, позволяющий выключить дружественный интерфейс + */ + public static void turnOffFriendly() { + friendlyInterface = false; + } + + /** + * Запрашивает ввод команды + * @param in + * @return + */ + public static String askCommand(InputHandler in) { + String command = null; + while(command == null) { + printMessage("Введите команду:"); + try { + command = in.readInput(); + CommandType.valueOf(command.toUpperCase()).ordinal(); + } catch(IllegalArgumentException e) { + if(!command.isEmpty()) System.err.print("Команада введена неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку\n"); + command = null; + } + } + return command; + } + + /** + * Метды запроса и обработки полей класса HumanBeing + * @param in - объект класса хендлеров, позволяющий считывать данные либо с консоли, либо с файла + * @return корректное запрошенное поле класса + */ + public static int askId(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Введите id: "); + try { + input = in.readInput(); + if(Integer.parseInt(input) <= 0) throw new NumberFormatException(); + } catch(NumberFormatException e) { + if(!input.isEmpty()) System.err.print("Id введен неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + return Integer.parseInt(input); + } + + public String askName(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Введите имя: "); + try { + input = in.readInput(); + if(input.isEmpty()) throw new IllegalArgumentException(); + } catch (IllegalArgumentException e) { + System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + return input; + } + + public String askSoundtrackName(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Введите название саундтрека:"); + try { + input = in.readInput(); + if(input.isEmpty()) throw new IllegalArgumentException(); + } catch (IllegalArgumentException e) { + System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + return input; + } + + public Long askMinutesOfWaiting(InputHandler in){ + String input = null; + while(input == null) { + printMessage("Введите минуты ожидания: "); + try { + input = in.readInput(); + Long.parseLong(input); + } catch(NumberFormatException e) { + if(!input.isEmpty()) System.err.print("Поле minutesOfWaiting введено неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + return Long.parseLong(input); + } + + public int askImpactSpeed(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Введите скорость: "); + try { + input = in.readInput(); + Integer.parseInt(input); + } catch(NumberFormatException e) { + if(!input.isEmpty()) System.err.print("Поле impactSpeed введено неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + return Integer.parseInt(input); + } + + public Boolean askRealHero(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Был героем?"); + try { + input = in.readInput(); + getBooleanInput(input); + } catch(NumberFormatException e) { + System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } catch (IllegalArgumentException e) { + System.err.print("Поле realHero введено неверно. Повторите попытку.\n"); + input = null; + } + } + return getBooleanInput(input); + } + + public Boolean askHasToothpick(InputHandler in) { + String input = null; + while(input == null) { + printMessage("Пользовался зубочисткой?"); + try { + input = in.readInput(); + getBooleanInput(input); + } catch(NumberFormatException e) { + System.out.print("\u001B[33mВы ввели пустую строку. Поле примет значение null.\u001B[0m\n"); + return null; + } catch (IllegalArgumentException e) { + System.err.print("Поле realHero введено неверно. Повторите попытку.\n"); + input = null; + } + } + return getBooleanInput(input); + } + + public Coordinates askCoordinates(InputHandler in) { + printMessage("Для определения местоположения персонажа введите координаты."); + String input = null; + while(input == null) { + printMessage("Введите координату x: "); + try { + input = in.readInput(); + Integer.parseInt(input); + } catch(NumberFormatException e) { + if(!input.isEmpty()) System.err.print("Координата x введена неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + int x = Integer.parseInt(input); + input = null; + while(input == null) { + printMessage("Введите координату y: "); + try { + input = in.readInput(); + if(Float.parseFloat(input) < -188) throw new NumberFormatException(); + } catch(NumberFormatException e) { + if(!input.isEmpty()) System.err.print("Координата y введена неверно. Повторите попытку.\n"); + else System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } + } + Float y = Float.parseFloat(input); + return new Coordinates(x, y); + } + + public Mood askMood(InputHandler in){ + String input = null; + while(input == null) { + printMessage("Введите состояние персонажа (sadness, longing, gloom or rage): "); + try { + input = in.readInput(); + if(input.isEmpty()) throw new NumberFormatException(); + Mood.valueOf(input.toUpperCase()); + } catch(NumberFormatException e) { + System.out.print("\u001B[33mВы ввели пустую строку. Поле примет значение null.\u001B[0m\n"); + return null; + } catch (IllegalArgumentException e) { + System.err.print("Поле mood введено неверно. Повторите попытку.\n"); + input = null; + } + } + return Mood.valueOf(input.toUpperCase()); + } + + public Car askCar(InputHandler in){ + printMessage("Введите машину, принадлежащую персонажу."); + String input = null; + String name = null; + while(input == null) { + printMessage("Введите её название: "); + try { + input = in.readInput(); + name = input; + if(input.isEmpty()) throw new IllegalArgumentException(); + } catch(IllegalArgumentException e) { + System.out.print("\u001B[33mВы ввели пустую строку. Поле примет значение null.\u001B[0m\n"); + name = null; + } + } + input = null; + while(input == null) { + printMessage("Машина крутая? "); + try { + input = in.readInput(); + getBooleanInput(input); + } catch(NumberFormatException e) { + System.err.print("Вы ввели пустую строку. Повторите попытку.\n"); + input = null; + } catch (IllegalArgumentException e) { + System.err.print("Поле cool введено неверно. Повторите попытку.\n"); + input = null; + } + } + boolean cool = getBooleanInput(input); + return new Car(name, cool); + } + + public FileInputStream askFileName(InputHandler in) { + FileInputStream fileInput = null; + while(fileInput == null) { + printMessage("Введите путь до файла, который хотите прочесть.\n"); + String fileName = in.readInput(); + try { + fileInput = new FileInputStream(fileName); + } catch (FileNotFoundException e) { + printMessage("Файл не найден. Проверьте корректность указанного пути.\n"); + fileInput = null; + } + } + return fileInput; + } + + /** + * Внутренний метод для более удобного преобразования String в Boolean + * @param input строка, которая будет преобразовываться в Boolean + * @return true (если в строке присутствует true, yes, да вне зависимости от регистра), false (если в строке присутствует false, no, нет или если строка пустая) + */ + private static Boolean getBooleanInput(String input) { + input = input.toLowerCase(); + if (input.equals("true") || input.equals("yes") || input.equals("да")) { + return true; + } else if (input.equals("false") || input.equals("no") || input.equals("нет")) { + return false; + } else if (!input.isEmpty()) throw new IllegalArgumentException(); + else throw new NumberFormatException(); + } + /** + * Внутренний метод для вывода сообщения относительно friendlyInterface + * @param message строка, которая будет напечатана, если дружественный интерфейс включен + */ + private static void printMessage(String message){ + if (friendlyInterface) { + System.out.println(message); + } + } +} diff --git a/src/service/CommandManager.java b/src/service/CommandManager.java new file mode 100644 index 0000000..596889e --- /dev/null +++ b/src/service/CommandManager.java @@ -0,0 +1,83 @@ +package service; + +import commands.*; +import dao.*; +import handlers.ConsoleInputHandler; +import handlers.FileInputHandler; +import handlers.InputHandler; +import source.HumanBeing; + +import java.io.BufferedInputStream; +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Класс обработчик, определяющий команду и ее поведение по отношению к входным данным + */ +public class CommandManager { + private static final DAO database = new ArrayDequeDAO(); + private static InputHandler reader; + + private static final Command[] commands = { + new AddCommand(database), + new ClearCommand(database), + new HeadCommand(database), + new HelpCommand(), + new InfoCommand(database), + // new ReadCommand(database), + new RemoveCommand(database), + new RemoveHeadCommand(database), + new ScriptCommand(), + new ShowCommand(database), + new UpdateCommand(database) + }; + + /** + * Меняет тип считывания на считывание с консоли + */ + public static void turnOnConsole() { + reader = new ConsoleInputHandler(); + } + + /** + * Меняет тип считывания на считывание с файла. + * Отключает дружественный интерфейс, если он включён + */ + public static void turnOnFile(BufferedInputStream bufferedInput) { + reader = new FileInputHandler(bufferedInput); + AskInput.turnOffFriendly(); + } + + /** + * Начало работы определителя команд + */ + public static void start() { + whichCommand(AskInput.askCommand(reader)); + } + + /** + * По полученной строке определяет команду и совершает её вызов + * @param command уже прошедшая проверку строка, содержащая команду + */ + private static void whichCommand(String command) { + int commandIndex = CommandType.valueOf(command.toUpperCase()).ordinal(); + commands[commandIndex].execute(reader); + start(); + } +} + +/** + * Перечисление существующих команд + */ +enum CommandType { + ADD, + CLEAR, + HEAD, + HELP, + INFO, + REMOVE_BY_ID, + REMOVE_HEAD, + EXECUTE_SCRIPT, + SHOW, + UPDATE; +} diff --git a/src/service/FormedManager.java b/src/service/FormedManager.java index 947904e..64a961f 100644 --- a/src/service/FormedManager.java +++ b/src/service/FormedManager.java @@ -1,27 +1,22 @@ package service; -import human_being.Car; -import human_being.Coordinates; -import human_being.HumanBeing; -import human_being.Mood; +import handlers.InputHandler; +import source.HumanBeing; public class FormedManager { + private final AskInput request = new AskInput(); - public HumanBeing formed(String arguments) { - String[] fields = arguments.split(" "); - for (String field : fields) { - System.out.print(field + " "); - } + public HumanBeing formed(InputHandler reader) { return new HumanBeing( - fields[0], - fields[1], - Long.parseLong(fields[2]), - Integer.parseInt(fields[3]), - Boolean.parseBoolean(fields[4]), - Boolean.parseBoolean(fields[5]), - new Coordinates(Integer.parseInt(fields[6]), Float.parseFloat(fields[7])), - Mood.valueOf(fields[8].toUpperCase()), - new Car(fields[9], Boolean.parseBoolean(fields[10])) + request.askName(reader), + request.askSoundtrackName(reader), + request.askMinutesOfWaiting(reader), + request.askImpactSpeed(reader), + request.askRealHero(reader), + request.askHasToothpick(reader), + request.askCoordinates(reader), + request.askMood(reader), + request.askCar(reader) ); } diff --git a/src/service/GenerateID.java b/src/service/GenerateID.java deleted file mode 100644 index 11ae345..0000000 --- a/src/service/GenerateID.java +++ /dev/null @@ -1,11 +0,0 @@ -package service; - -import human_being.HumanBeing; - -import java.util.ArrayDeque; - -public class GenerateID { - public GenerateID(ArrayDeque humanCollection, HumanBeing human){ - human.setId(humanCollection.size() + 1); - } -} \ No newline at end of file diff --git a/src/service/Generator.java b/src/service/Generator.java new file mode 100644 index 0000000..9d2be9a --- /dev/null +++ b/src/service/Generator.java @@ -0,0 +1,28 @@ +package service; + +import source.HumanBeing; + +import java.time.LocalDate; + +/** + * Класс для генерации айди и даты создания элемента + */ +public class Generator { + private static int availableId = 1; + + /** + * Автоматически генерирует айди + * @param human экземпляр класса, которому устанавливается данное айди + */ + public void generateID(HumanBeing human){ + human.setId(availableId++); + } + + /** + * Автоматически генерирует дату создания экземпляра + * @param humanBeing экземпляр класса, дата создания которого генерируется + */ + public void generateCreationDate(HumanBeing humanBeing){ + humanBeing.setCreationDate(LocalDate.now()); + } +} diff --git a/src/source/Car.java b/src/source/Car.java new file mode 100644 index 0000000..5b2e27d --- /dev/null +++ b/src/source/Car.java @@ -0,0 +1,59 @@ +package source; + +public class Car implements Comparable { + private String name; //Поле может быть null + private boolean cool; + + public Car(String name, boolean cool){ + this.name = name; + this.cool = cool; + } + + public Car(boolean cool){ + this.name = null; + this.cool = cool; + } + + public void setCarName(String name) { + this.name = name; + } + + public void setCarCool(boolean cool) { + this.cool = cool; + } + + public String getCarName() { + return name; + } + + public Boolean getCarCool(){ + return cool; + } + + @Override + public int compareTo(Object o) { + Car car = (Car) o; + int result = this.name.compareTo(car.name); + if (result == 0){ + result = Boolean.compare(this.cool, car.cool); + } + return result; + } + + private String getStringName(){ + if (getCarName() != null){ + return getCarName() + ", "; + } else { + return ""; + } + } + + @Override + public String toString(){ + if (getCarCool()){ + return getStringName() + "крутая тачка"; + } else { + return getStringName() + "среднячок"; + } + } +} diff --git a/src/human_being/Coordinates.java b/src/source/Coordinates.java similarity index 71% rename from src/human_being/Coordinates.java rename to src/source/Coordinates.java index ed788d5..77c8415 100644 --- a/src/human_being/Coordinates.java +++ b/src/source/Coordinates.java @@ -1,4 +1,4 @@ -package human_being; +package source; public class Coordinates { private final int x; @@ -8,4 +8,9 @@ public Coordinates(int x, Float y){ this.x = x; this.y = y; } -} \ No newline at end of file + + @Override + public String toString(){ + return "(" + x + ", " + y + ")"; + } +} diff --git a/src/human_being/HumanBeing.java b/src/source/HumanBeing.java similarity index 80% rename from src/human_being/HumanBeing.java rename to src/source/HumanBeing.java index e9bb545..db1267b 100644 --- a/src/human_being/HumanBeing.java +++ b/src/source/HumanBeing.java @@ -1,4 +1,4 @@ -package human_being; +package source; import java.time.LocalDate; @@ -10,7 +10,7 @@ public class HumanBeing implements Comparable { private java.time.LocalDate creationDate; //Поле не может быть null, Значение этого поля должно // генерироваться автоматически private boolean realHero; - private boolean hasToothpick; //Поле может быть null + private Boolean hasToothpick; //Поле может быть null private int impactSpeed; private String soundtrackName; //Поле не может быть null private Long minutesOfWaiting; //Поле не может быть null @@ -19,8 +19,7 @@ public class HumanBeing implements Comparable { public HumanBeing(String name, String soundtrackName, Long minutesOfWaiting, int impactSpeed, - boolean realHero, boolean hasToothpick, Coordinates coordinates, - Mood mood, Car car) { + boolean realHero, Boolean hasToothpick, Coordinates coordinates, Mood mood, Car car) { this.name = name; this.soundtrackName = soundtrackName; this.minutesOfWaiting = minutesOfWaiting; @@ -121,7 +120,9 @@ public Car getCar() { return car; } - // переобределение метода compareTo для сортировки + /** + * переобределение метода compareTo для сортировки + */ @Override public int compareTo(Object o) { if (o == null){ @@ -154,10 +155,27 @@ public int compareTo(Object o) { } return result; } - // TODO переопределить нормально - public String toString() { - System.out.print(name + soundtrackName + minutesOfWaiting + impactSpeed + realHero + hasToothpick + - coordinates+ mood + car); - return null; + + private String getStringMood(){ + if (getMood() == null) { + return "нет"; + } else { + return getMood().toString(); + } + } + + private String getStringToothpick(){ + if (hasToothpick == null){ + return "нет"; + } else { + return String.valueOf(isHasToothpick()); + } + } + + @Override + public String toString(){ + return "Имя - " + getName() + ", саундтрек - " + getSoundtrackName() + ", настроение - " + getStringMood() + + ", машина - " + getCar().toString() + ", координаты - " + getCoordinates().toString() + ", статус героя - " + isRealHero() + + ", статус зубочистки - " + getStringToothpick() + ", ждёт " + getMinutesOfWaiting().toString() + " минут(ы)."; } } diff --git a/src/human_being/Mood.java b/src/source/Mood.java similarity index 66% rename from src/human_being/Mood.java rename to src/source/Mood.java index d4120c7..1096b7d 100644 --- a/src/human_being/Mood.java +++ b/src/source/Mood.java @@ -1,8 +1,10 @@ -package human_being; +package source; public enum Mood { SADNESS, LONGING, GLOOM, - RAGE + RAGE; + + }