Полезный класс, который позволяет быстро и легко создавать консольные приложения в Java.
Для того, чтобы начать использовать ConsoleScanner достаточно просто создать объект, и передать ему в качестве параметров префикс команды и префикс параметра
ConsoleScanner scanner = new ConsoleScanner("/", "-");
В таком виде сканнер будет работать синхронно с приложением, и считать ввод вы сможете с помощью вызова метода scanner.scan()
. Если же вызвать конструктор с boolean параметром false
, то сканнер будет работать в асинхронном режиме, и все команды, которые в него добавлены, будут выполняться в отдельном потоке:
ConsoleScanner scanner = new ConsoleScanner("/", "-", false);
В случае использования асинхронного метода для начала сканнирования вызовите на объектре сканнера метод scanner.start()
, а для остановки scanner.stop()
.
Внутри класса ConsoleScanner имеется список добавленных в него команд, которые представлены классом Command
. Для добавление новой команды в сканнер создайте экземпляр класса Command, и в качестве параметров передайте ему имя команды и краткое описание.
Command command = new Command("test", "This is a test command");
Затем добавьте команду в сканнер вызвав на последнем метод scanner.addCommand(command)
. Сканнер сам подхватит ее во время работы (синхронной или нет).
После того, как вы создали и добавили в сканнер команду стоит задать для нее логику выполнения. В ходе своей работы сканнер читает входящий поток, и, при совпадении с командой на входе, он разбирает входящую строку на параметры исподьзуя данные о префиксе параметров, переданные ему через конструктор. Пример для команды test: /test -n Name -s Surname
, где -n и -s параметры команды, а Name и Surname значения этих параметров.
Так как одному параметру может соответствовать несколько значений сканнер складывает каждое значение для параметра во внутренний список List<String> values;
, затем создает карту Map<String, List<String>> params;
и используя имя параметра как ключь заносит все списки в соответствующие места в карте. После чего передает управление внутреннему методу, который передает текущую карту параметров на выполнение объекту, который расширяет интерфейс Consumable
и находится внутри объекта соответствующей команды. Все, что остается программисту - это определить поведение этого самого объекта Consumable
Для того, чтобы определить объект расширяющий интерфейс Consumable нужно вызвать на команде метод setConsumer(Consumable consumable)
. Пример кода:
command.setConsumer(new Consumable() {
@Override
public void consume(Map<String, List<String>> map) {
//Логика команды
}
});
Естественно, вместо анонимного класса можно использовать внутренний, или использовать лямбду:
command.setConsumer(map -> {
//Логика команды
});
При этом передоваемая методу consume карта - это набор параметров и их значений в соответствии со спецификациями карты. Иногда возникает необходимость при вызове команды передовать ей значения без параметров /test something
. В таком случает в сканнере предусмотрен ключь по умолчанию, который будет использоват для помещения значений в карту параметров. Значение этого ключа можно получить и задать программно.
Стоит отметить, что метод setConsumer(Consmable consumable);
возвращает сам себя (объект типа Command), и его можно вызывать в ходе инициализации экземпляра класса Command scanner.addCommand(new Command("test, "").setConsumer(new Consumable()...));
Метод scanner.setWelcome(String s)
позволяет задать сообщение приветствия, которое появляется автоматически при асинхронной работе сканера. Если вы не хотите, чтобы оно отображалось - просто передайте в качетве параметра пустые скобки строки "".
Методы scanner.getCommandPrefix()
и scanner.setCommandPrefix(String prefix)
можно использовать для получения строки префикса команды, и для ее установки вне конструктора соответственно.
Методы scanner.getParamPrefix()
и scanner.setParamPrefix(String prefix)
можно использовать для получения строки префикса параметра, и для ее установки вне конструктора соответственно.
Методы scanner.getDefaultKey()
и scanner.setDefaultKey(String key)
можно использовать для получения строки ключа по умолчанию, и для ее установки соответственно.
Синхронная программа пересмешник:
import by.zti.main.scanner.Command;
import by.zti.main.scanner.ConsoleScanner;
public class Main {
public static void main(String[] args) {
ConsoleScanner scanner = new ConsoleScanner("/", "-");
scanner.addCommand(new Command("say", "").setConsumer(map -> map.get(scanner.getDefaultKey()).forEach(System.out::println)));
scanner.scan();
}
}
Вывод:
/say Hello
Hello
Process finished with exit code 0
Асинхронная программа пересмешник с командой для выхода:
import by.zti.main.scanner.Command;
import by.zti.main.scanner.ConsoleScanner;
public class Main {
public static void main(String[] args) {
ConsoleScanner scanner = new ConsoleScanner("/", "-", false);
scanner.setWelcome("");
scanner.addCommand(new Command("say", "").setConsumer(map -> map.get(scanner.getDefaultKey()).forEach(System.out::println)));
scanner.addCommand(new Command("exit", "").setConsumer(map -> scanner.stop()));
scanner.start();
}
}
Вывод:
/say Hello
Hello
/exit
Process finished with exit code 0
Класс, реализующий процесс сериализации объектов, расширяющих интерфейс Serializable.
Для того, чтобы использовать сереализатор, необходимо создать экземпляр класса, и указать тип данных с которым он будет работать, а в качестве параметра передать путь к фалу в который (из которого) будет произведена сериализация\десериализация, или объект типа File.
Serializer<Object> serializer = new Serializer<>(String filePath);
Вместо типа данных Object укажите тип данных, с которым будет работать данный экземпляр
Для того, чтобы провести операцию сереализации достаточно вызвать на объекте метод serializer.serialaize(Object obj)
, котоырй сереализирует объект в файл по пути заданному в конструкторе при инициализации, или в файл переданный в конструктор.
Пример кода сереализации строки в файл:
import by.zti.main.serializer.Serializer;
public class Main {
public static void main(String[] args) {
Serializer<String> serializer = new Serializer<>("test.ser");
serializer.serialize("Test string");
}
}
В результате выполнения кода в корне программы появится файл с названием "test", и расширением "ser" (test.ser).
Для того, чтобы десереализовать объект из файла по пути, или файла переданного в конструктор при инициализации достаточно просто вызвать на сериализаторе метод serializer.deserialize()
, котоырй вернет объект типа соответствующего тому, который был задан при объявлении сериализатора.
Пример десериализации строки из файла:
import by.zti.main.serializer.Serializer;
public class Main {
public static void main(String[] args) {
Serializer<String> serializer = new Serializer<>("test.ser");
System.out.println(serializer.deserialize());
}
}
Вывод:
Test string
Process finished with exit code 0
В Maven Central разумеется :D
<dependency>
<groupId>com.github.cvazer</groupId>
<artifactId>zti-utils-scanner</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<dependency>
<groupId>com.github.cvazer</groupId>
<artifactId>zti-utils-serializer</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.github.cvazer</groupId>
<artifactId>zti-utils-incubator</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.github.cvazer</groupId>
<artifactId>zti-utils-legacy</artifactId>
<version>1.1.0</version>
</dependency>