diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/client/Client.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/client/Client.java
index 9adc491..6a1e4b4 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/client/Client.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/client/Client.java
@@ -26,23 +26,16 @@ public class Client {
if (sendMessage(new BodylessMessage(MessageType.HELLO)).getType() == MessageType.HELLO) {
Console.log(String.format("Соединение с сервером %s:%s установлено", address, port));
}
- } catch (IOException e) {
- throw new ConnectionErrorException();
- } catch (ClassNotFoundException e) {
+ } catch (IOException | ClassNotFoundException e) {
throw new ResponseException();
}
}
- public Message sendMessage(Message message) throws IOException, ClassNotFoundException {
+ public Message sendMessage(Message message) throws ClassNotFoundException, IOException {
try (var socket = new Socket(address, port);
var bufferedSocketOutputStream = new BufferedOutputStream(socket.getOutputStream());
var byteArrayOutputStream = new ByteArrayOutputStream();
var objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)) {
- int connectionTries = 0;
- while(!socket.isConnected()) {
- if (connectionTries++ > 5) throw new IOException();
- Thread.sleep(10 + (long) connectionTries * connectionTries*100);
- }
objectOutputStream.writeObject(message);
objectOutputStream.flush();
@@ -52,8 +45,8 @@ public class Client {
try (var objectInputStream = new ObjectInputStream(socket.getInputStream())) {
return (Message) objectInputStream.readObject();
}
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new IOException("Сервер не доступен");
}
}
}
diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Add.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Add.java
index 60e8f30..89d02e1 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Add.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Add.java
@@ -26,7 +26,8 @@ public class Add extends Command {
public String action(Client client) throws CommandActionException {
try {
var productDTO = Console.readProductDTO();
- var response = (BodylessMessage) client.sendMessage(new BodyfulMessage(MessageType.POST, Console.getLastCommand(), productDTO));
+ var request = new BodyfulMessage(MessageType.POST, Console.getLastCommand(), productDTO);
+ var response = (BodylessMessage) client.sendMessage(request);
return response.getBody().toString();
} catch (IOException | ClassNotFoundException e) {
throw new CommandActionException(e);
diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/IsIdExists.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/IsIdExists.java
index fe08961..04a81fc 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/IsIdExists.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/IsIdExists.java
@@ -20,7 +20,7 @@ public class IsIdExists extends Command {
try {
Long id = Long.parseLong(Console.getLastCommand().split(" ")[1]);
var response = (BodylessMessage) client.sendMessage(new BodyfulMessage(MessageType.POST, Console.getLastCommand(), id));
- if (response.getType() == MessageType.ERROR) throw new CommandActionException();
+ if (response.getType() == MessageType.ERROR) throw new CommandActionException(response.getBody().toString());
return response.getBody().toString();
} catch (IOException | ClassNotFoundException e) {
throw new CommandActionException(e);
diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Save.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Save.java
index 7c5a97a..95c0cf8 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Save.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Save.java
@@ -11,6 +11,6 @@ import java.io.IOException;
*/
public class Save extends Command {
public Save() {
- super("save", "сохранить коллекцию в файл");
+ super("save", "save the collection to a file");
}
}
diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Update.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Update.java
index cb21d98..545681b 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Update.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/commands/Update.java
@@ -7,11 +7,6 @@ import me.zinch.Lab6.Domain.dto.BodyfulMessage;
import me.zinch.Lab6.Domain.dto.BodylessMessage;
import me.zinch.Lab6.Domain.dto.MessageBody;
import me.zinch.Lab6.Domain.dto.MessageType;
-import me.zinch.Lab6.Domain.dto.UpdateBody;
-import me.zinch.Lab6.Domain.exceptions.ValidationException;
-import me.zinch.Lab6.Domain.models.ProductDTO;
-import me.zinch.Lab6.Domain.validator.Validators;
-import me.zinch.Lab6.Domain.wrapper.IStorage;
import java.io.IOException;
import java.util.regex.Pattern;
@@ -27,18 +22,26 @@ public class Update extends Command {
@Override
public String action(Client client) throws CommandActionException {
try {
- Long id = Long.parseLong(Console.getLastCommand().split(" ")[1]);
+ var command = Console.getLastCommand();
+ Long id = Long.parseLong(command.split(" ")[1]);
var isIdExists = new IsIdExists();
- Console.appendHistory(String.format("%s %s", isIdExists.getName(), id));
+ Console.appendHistory(String.format("%s %s", isIdExists.getSignature(), id));
isIdExists.action(client);
+ var getProductById = new GetProductById();
+ Console.appendHistory(String.format("%s %s", getProductById.getSignature(), id));
+ var product = getProductById.action(client);
+
+ Console.log("Вы собираетесь обновить следующий продукт");
+ Console.log(product);
+
var productDTO = Console.readProductDTO();
var response = (BodylessMessage) client.sendMessage(
- new BodyfulMessage(MessageType.POST, this.getSignature(),
- new MessageBody(String.format("%s %s", this.getSignature(), id), productDTO)));
+ new BodyfulMessage(MessageType.POST, command,
+ new MessageBody(String.format("%s %s", command, id), productDTO)));
return response.getBody().toString();
- } catch (IOException | ClassNotFoundException e) {
+ } catch (IOException | ClassNotFoundException | NumberFormatException e) {
throw new CommandActionException(e);
}
}
diff --git a/Lab.Client/src/main/java/me/zinch/Lab6/Client/console/Console.java b/Lab.Client/src/main/java/me/zinch/Lab6/Client/console/Console.java
index dc22f69..e535f4b 100644
--- a/Lab.Client/src/main/java/me/zinch/Lab6/Client/console/Console.java
+++ b/Lab.Client/src/main/java/me/zinch/Lab6/Client/console/Console.java
@@ -171,13 +171,14 @@ public class Console {
public static void run() {
while (client == null) {
- var address = readField("Хост");
- int port = Integer.parseInt(readField("Порт"));
try {
+ var address = readField("Хост");
+ int port = Integer.parseInt(readField("Порт"));
client = new Client(address, port);
+ } catch (NumberFormatException e) {
+ log("Порт должен быть числом от 1 до 65535");
} catch (ResponseException | ConnectionErrorException e) {
- log(e.getMessage());
- log("Попробуйте ещё раз");
+ log("Ошибка при подключении\nПопробуйте ещё раз");
}
}
diff --git a/Lab.Server/pom.xml b/Lab.Server/pom.xml
index 990b32f..1cd1302 100644
--- a/Lab.Server/pom.xml
+++ b/Lab.Server/pom.xml
@@ -57,6 +57,17 @@
1.0-SNAPSHOT
compile
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.17.1
+ compile
+
+
+ org.jline
+ jline
+ 3.26.1
+
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/App.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/App.java
index 7f8b8a7..af636c0 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/App.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/App.java
@@ -1,6 +1,9 @@
package me.zinch.Lab6.Server;
import me.zinch.Lab6.Server.console.Console;
+import me.zinch.Lab6.Server.console.ShutdownHook;
+import me.zinch.Lab6.Server.files.DbController;
+import me.zinch.Lab6.Server.wrapper.ProductCollection;
import java.io.IOException;
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/Server.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/Server.java
index 9a37ace..e8afff8 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/Server.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/Server.java
@@ -8,6 +8,8 @@ import me.zinch.Lab6.Domain.wrapper.IStorage;
import me.zinch.Lab6.Server.commands.CommandManager;
import me.zinch.Lab6.Server.commands.GetCommand;
import me.zinch.Lab6.Server.commands.PostCommand;
+import me.zinch.Lab6.Server.exceptions.CommandActionException;
+import me.zinch.Lab6.Server.files.DbController;
import me.zinch.Lab6.Server.wrapper.ProductCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,6 +28,7 @@ import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
+import java.text.Normalizer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -53,10 +56,15 @@ public class Server {
}
public void run() throws IOException {
+ run(() -> {});
+ }
+
+ public void run(Runnable middleware) throws IOException {
log.info("The server is running");
while (isRunning) {
selector.select(this::handleKey);
+ middleware.run();
}
}
@@ -134,8 +142,12 @@ public class Server {
log.error("Command {} not found", inputCommand);
return serialize(new BodylessMessage(MessageType.ERROR, String.format("Command %s not found", inputCommand)));
}
- var action = (GetCommand) command.get();
- return serialize(new BodylessMessage(MessageType.OK, action.action(storage)));
+ try {
+ var action = (GetCommand) command.get();
+ return serialize(new BodylessMessage(MessageType.OK, action.action(storage)));
+ } catch (CommandActionException e) {
+ return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage()));
+ }
}
private ByteBuffer handlePostCommand(MessageBody request) throws IOException {
@@ -148,8 +160,12 @@ public class Server {
return serialize(new BodylessMessage(MessageType.ERROR, String.format("Command %s not found", inputCommand)));
}
- var action = (PostCommand) command.get();
- return serialize(new BodylessMessage(MessageType.OK, action.action(storage, body)));
+ try {
+ var action = (PostCommand) command.get();
+ return serialize(new BodylessMessage(MessageType.OK, action.action(storage, body)));
+ } catch (CommandActionException e) {
+ return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage()));
+ }
}
public static ByteBuffer serialize(Serializable obj) throws IOException {
@@ -165,5 +181,6 @@ public class Server {
isRunning = false;
serverSocketChannel.close();
selector.close();
+ DbController.saveDb(storage.toList());
}
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/CommandManager.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/CommandManager.java
index 6bdd111..3f540ad 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/CommandManager.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/CommandManager.java
@@ -41,6 +41,7 @@ public class CommandManager {
registerCommand(new AddIfMin());
registerCommand(new RemoveLower());
registerCommand(new Save());
+ registerCommand(new GetProduct());
registerCommand(new Help());
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Exit.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Exit.java
index 6d0c677..2683839 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Exit.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Exit.java
@@ -8,7 +8,7 @@ import me.zinch.Lab6.Server.console.Console;
*/
public class Exit extends GetCommand {
public Exit() {
- super("exit", "завершить программу (без сохранения в файл)");
+ super("exit", "terminate the program (without saving to a file)");
}
@Override
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/GetProduct.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/GetProduct.java
new file mode 100644
index 0000000..221573d
--- /dev/null
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/GetProduct.java
@@ -0,0 +1,18 @@
+package me.zinch.Lab6.Server.commands;
+
+import me.zinch.Lab6.Domain.wrapper.IStorage;
+import me.zinch.Lab6.Server.exceptions.CommandActionException;
+
+import java.util.regex.Pattern;
+
+public class GetProduct extends PostCommand {
+ public GetProduct() {
+ super("get_product_by_id", "", Pattern.compile("^get_product_by_id +."));
+ }
+
+ @Override
+ public String action(IStorage productCollection, Object obj) throws CommandActionException {
+ if (!productCollection.isProductIdExists((Long) obj)) throw new CommandActionException("Продукт с таким ID не существует");
+ return productCollection.getProductById((Long) obj).toString();
+ }
+}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Help.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Help.java
index 04bfec3..ffcb379 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Help.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/Help.java
@@ -7,11 +7,11 @@ import me.zinch.Lab6.Domain.wrapper.IStorage;
*/
public class Help extends GetCommand {
public Help() {
- super("help", "вывести справку по доступным командам");
+ super("help", "display help for available commands");
}
@Override
public String action(IStorage productCollection) {
- return CommandManager.getRegisteredCommand();
+ return SystemCommandManager.getRegisteredCommand();
}
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/IsIdExists.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/IsIdExists.java
index 99ec334..12fbb75 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/IsIdExists.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/commands/IsIdExists.java
@@ -12,7 +12,7 @@ public class IsIdExists extends PostCommand {
@Override
public String action(IStorage productCollection, Object obj) throws CommandActionException {
- if (!productCollection.isProductIdExists((Long) obj)) throw new CommandActionException();
- return null;
+ if (!productCollection.isProductIdExists((Long) obj)) throw new CommandActionException("Продукт с таким ID не существует");
+ return "Exists";
}
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/Console.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/Console.java
index 5a6c80d..96edce8 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/Console.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/Console.java
@@ -1,12 +1,15 @@
package me.zinch.Lab6.Server.console;
import me.zinch.Lab6.Domain.exceptions.ValidationException;
+import me.zinch.Lab6.Domain.wrapper.IStorage;
import me.zinch.Lab6.Server.ServerBuilder;
import me.zinch.Lab6.Server.commands.GetCommand;
import me.zinch.Lab6.Server.commands.SystemCommandManager;
import me.zinch.Lab6.Server.exceptions.CommandActionException;
import me.zinch.Lab6.Server.files.DbController;
import me.zinch.Lab6.Server.wrapper.ProductCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.NoSuchElementException;
@@ -18,67 +21,66 @@ import java.util.Scanner;
*/
public class Console {
private static final Scanner scanner = new Scanner(System.in);
+ private static final Logger log = LoggerFactory.getLogger(Console.class);
private static boolean isRunning = true;
private static boolean isExitMessageShowed = false;
-
- public static void log(String msg) {
- if (isRunning) System.out.println(msg);
- }
-
- public static void log() {
- log("");
- }
+ private static IStorage collection;
public static void stopApp() {
showExitMessage();
isRunning = false;
+ System.exit(0);
}
public static void showExitMessage() {
- if (!isExitMessageShowed) log("\nВсего хорошего!");
+ if (!isExitMessageShowed) log.info("Have a nice day!");
isExitMessageShowed = true;
}
- private static String readString() {
- if (!scanner.hasNextLine()) Console.stopApp();
- var input = scanner.nextLine().trim();
- return input.isEmpty() ? null : input;
- }
-
public static void run() throws IOException, ValidationException {
- var collection = new ProductCollection(DbController.loadDb());
+ collection = new ProductCollection(DbController.loadDb());
var server = new ServerBuilder()
.setPort(3000)
.setCollection(collection)
.build();
+
+ Console.handleInput();
+
server.run();
- log("Добро пожаловать! Для просмотра команд введите help");
-
- while(isRunning) {
- System.out.print(":");
-
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ Console.stopApp();
try {
- var input = scanner.nextLine().trim();
- var command = SystemCommandManager.getCommandByInput(input);
-
- if (command.isPresent()) {
- var action = (GetCommand) command.get();
- try {
- log(action.action(null));
- } catch (CommandActionException e) {
- log(e.getMessage());
- }
- } else {
- log("Такой команды не существует. Напишите help, чтобы посмотреть список доступных команд.");
- }
- } catch (NoSuchElementException e) {
- stopApp();
+ server.stop();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
- log();
- }
- scanner.close();
- server.stop();
+ }));
+ }
+
+ public static void handleInput() {
+ new Thread(() -> {
+ while(isRunning) {
+ try {
+ var input = scanner.nextLine().trim();
+ var command = SystemCommandManager.getCommandByInput(input);
+
+ if (command.isPresent()) {
+ var action = (GetCommand) command.get();
+ try {
+ log.info(action.action(collection));
+ } catch (CommandActionException e) {
+ log.info(e.getMessage());
+ }
+ } else {
+ log.info("This command does not exist. Write help to see a list of available commands.");
+ }
+ } catch (NoSuchElementException e) {
+ stopApp();
+ }
+ }
+ scanner.close();
+ }).start();
}
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/ShutdownHook.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/ShutdownHook.java
index 15e61cd..2439529 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/ShutdownHook.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/console/ShutdownHook.java
@@ -5,6 +5,6 @@ package me.zinch.Lab6.Server.console;
*/
public class ShutdownHook extends Thread {
public ShutdownHook() {
- super(new Thread(Console::stopApp));
+ super();
}
}
diff --git a/Lab.Server/src/main/java/me/zinch/Lab6/Server/files/DbController.java b/Lab.Server/src/main/java/me/zinch/Lab6/Server/files/DbController.java
index 721ebfe..32112a3 100644
--- a/Lab.Server/src/main/java/me/zinch/Lab6/Server/files/DbController.java
+++ b/Lab.Server/src/main/java/me/zinch/Lab6/Server/files/DbController.java
@@ -48,7 +48,7 @@ public class DbController {
}
}
- public static List loadDb() throws IOException {
+ public static List loadDb() {
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(path));
List collection = xmlMapper.readValue(bufferedInputStream, Products.class).getProducts();
diff --git a/db.xml b/db.xml
index b41fb6f..449f999 100644
--- a/db.xml
+++ b/db.xml
@@ -1 +1 @@
-1Product 1100501709294400.00000000050PN12330KILOGRAMSJohn DoeAB12345BLACK10.520Home2Product 22001001709294700.00000000080PN45660CENTIMETERSAlice SmithCD67890BLUE20.830Office3Product 3150-2001709295000.00000000012090GRAMSEmma JohnsonEF24680GREEN30.240Warehouse4Product 4300-3001709295300.000000000200PN789150KILOGRAMSBob BrownGH13579ORANGE40.650Factory5Product 54004001709295600.000000000150PN246100CENTIMETERSGrace LeeIJ35791WHITE50.960Store611111716766945.58466260011231CENTIMETERS1313412BLACK1.011
\ No newline at end of file
+611111716766945.58466260011231CENTIMETERS1313412BLACK1.0111Product 1100501709294400.00000000050PN12330KILOGRAMSJohn DoeAB12345BLACK10.520Home2Product 22001001709294700.00000000080PN45660CENTIMETERSAlice SmithCD67890BLUE20.830Office3Product 3150-2001709295000.00000000012090GRAMSEmma JohnsonEF24680GREEN30.240Warehouse4Product 4300-3001709295300.000000000200PN789150KILOGRAMSBob BrownGH13579ORANGE40.650Factory5Product 54004001709295600.000000000150PN246100CENTIMETERSGrace LeeIJ35791WHITE50.960Store
\ No newline at end of file