From 8ea371d33b5032de2c4b40a798271a72078d2168 Mon Sep 17 00:00:00 2001 From: Ivan Zinchenko Date: Fri, 7 Jun 2024 23:09:21 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BA=20!3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/me/zinch/Lab7/Server/App.java | 16 ++++-- .../me/zinch/Lab7/Server/Server/Server.java | 53 +++++++++++-------- .../Lab7/Server/commands/CommandManager.java | 7 --- .../me/zinch/Lab7/Server/commands/Login.java | 4 +- .../zinch/Lab7/Server/commands/Register.java | 5 +- .../Server/commands/UnauthorizedCommand.java | 19 +++++++ .../Server/exceptions/NonExistentCommand.java | 21 ++++++++ .../exceptions/UnauthorizedException.java | 21 ++++++++ .../zinch/Lab7/Server/wrapper/AuthGuard.java | 19 +++++++ 9 files changed, 129 insertions(+), 36 deletions(-) create mode 100644 Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/UnauthorizedCommand.java create mode 100644 Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/NonExistentCommand.java create mode 100644 Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/UnauthorizedException.java create mode 100644 Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/AuthGuard.java diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/App.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/App.java index 6203d6a..3c50fd1 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/App.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/App.java @@ -1,13 +1,23 @@ package me.zinch.Lab7.Server; import me.zinch.Lab7.Server.console.Console; -import me.zinch.Lab7.Server.utils.SHA256; +import me.zinch.Lab7.Server.exceptions.DbConnectionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; /** * Main class for running the application. */ public class App { - public static void main(String[] args) throws Exception { - Console.run(); + private static final Logger log = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) { + try { + Console.run(); + } catch (IOException | DbConnectionException e) { + log.error(e.getMessage()); + } } } diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java index 2cfaf69..322ec0e 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java @@ -5,12 +5,15 @@ import me.zinch.Lab7.Domain.net.Message; import me.zinch.Lab7.Domain.net.MessageBody; import me.zinch.Lab7.Domain.net.MessageType; import me.zinch.Lab7.Domain.net.User; +import me.zinch.Lab7.Server.commands.UnauthorizedCommand; +import me.zinch.Lab7.Server.exceptions.DbExecuteException; +import me.zinch.Lab7.Server.exceptions.NonExistentCommand; import me.zinch.Lab7.Server.utils.SHA256; +import me.zinch.Lab7.Server.wrapper.AuthGuard; import me.zinch.Lab7.Server.wrapper.IStorage; import me.zinch.Lab7.Server.commands.CommandManager; import me.zinch.Lab7.Server.commands.GetCommand; import me.zinch.Lab7.Server.commands.PostCommand; -import me.zinch.Lab7.Server.exceptions.CommandActionException; import me.zinch.Lab7.Server.wrapper.ProductCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,11 +114,15 @@ public class Server { } } - private byte[] createResponse(Message message) throws IOException { + private byte[] createResponse(Message message) throws IOException, DbExecuteException { + if (message.getType() == MessageType.HELLO) return serialize(new BodylessMessage(MessageType.HELLO)); + var user = (User) message.getUser(); - if (user != null) user.setPassword(SHA256.hash(user.getPassword())); + if (user == null) return handleUnauthorizedCommand(message); + user.setPassword(SHA256.hash(user.getPassword())); + AuthGuard.throwIfUserNotValid(user); + return switch (message.getType()) { - case HELLO -> serialize(new BodylessMessage(MessageType.HELLO)); case GET -> handleGetCommand((String) message.getBody(), user); case POST -> handlePostCommand((MessageBody) message.getBody(), user); default -> { @@ -127,16 +134,10 @@ public class Server { private byte[] handleGetCommand(String inputCommand, User user) throws IOException { var command = CommandManager.getCommandByInput(inputCommand); - if (command.isEmpty()) { - log.error("Command {} not found", inputCommand); - return serialize(new BodylessMessage(MessageType.ERROR, String.format("Command %s not found", inputCommand))); - } - try { - var action = (GetCommand) command.get(); - return serialize(new BodylessMessage(MessageType.OK, action.action(storage, user))); - } catch (CommandActionException e) { - return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage())); - } + if (command.isEmpty()) throw new NonExistentCommand("Такой команды не существует"); + + var action = (GetCommand) command.get(); + return serialize(new BodylessMessage(MessageType.OK, action.action(storage, user))); } private byte[] handlePostCommand(MessageBody request, User user) throws IOException { @@ -144,15 +145,25 @@ public class Server { var body = request.getBody(); var command = CommandManager.getCommandByInput(inputCommand); - if (command.isEmpty()) { - log.error("Command {} not found", inputCommand); - return serialize(new BodylessMessage(MessageType.ERROR, String.format("Command %s not found", inputCommand))); - } + if (command.isEmpty()) throw new NonExistentCommand("Такой команды не существует"); + var action = (PostCommand) command.get(); + return serialize(new BodylessMessage(MessageType.OK, action.action(storage, body, user))); + } + + // Only get commands or else exception + private byte[] handleUnauthorizedCommand(Message message) throws IOException { try { - var action = (PostCommand) command.get(); - return serialize(new BodylessMessage(MessageType.OK, action.action(storage, body, user))); - } catch (CommandActionException e) { + var messageBody = (MessageBody) message.getBody(); + var inputCommand = messageBody.getCommand(); + var body = messageBody.getBody(); + + var command = CommandManager.getCommandByInput(inputCommand); + if (command.isEmpty()) throw new NonExistentCommand("Такой команды не существует"); + + var action = (UnauthorizedCommand) command.get(); + return serialize(new BodylessMessage(MessageType.OK, action.action(body))); + } catch (ClassCastException | NonExistentCommand e) { return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage())); } } diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/CommandManager.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/CommandManager.java index 63e6696..1c0d852 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/CommandManager.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/CommandManager.java @@ -37,13 +37,6 @@ public class CommandManager { commandList.add(command); } - public static String getRegisteredCommand() { - return String.join("\n", commandList - .stream() - .map(command -> String.format("%s - %s", command.getName(), command.getDescription())) - .toList()); - } - public static Optional getCommandByInput(String input) { return commandList.stream().filter(command -> command.checkPattern(input)).findFirst(); } diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Login.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Login.java index eb007b7..fc8af09 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Login.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Login.java @@ -9,13 +9,13 @@ import me.zinch.Lab7.Server.wrapper.IStorage; import java.sql.SQLException; -public class Login extends PostCommand { +public class Login extends UnauthorizedCommand { public Login() { super("login", ""); } @Override - public String action(IStorage productCollection, Object obj, User user) throws CommandActionException { + public String action( Object obj) throws CommandActionException { try { var loginUser = (User) obj; if (DbWrapper.isUserExists(loginUser.getLogin(), SHA256.hash(loginUser.getPassword()), DbController.getConnection())) diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Register.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Register.java index 49c01ef..95262de 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Register.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/Register.java @@ -9,13 +9,12 @@ import me.zinch.Lab7.Server.wrapper.IStorage; import java.sql.SQLException; -public class Register extends PostCommand { +public class Register extends UnauthorizedCommand { public Register() { super("register", ""); } - @Override - public String action(IStorage productCollection, Object obj, User user) throws CommandActionException { + public String action(Object obj) throws CommandActionException { try { var newUser = (User) obj; newUser.setPassword(SHA256.hash(newUser.getPassword())); diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/UnauthorizedCommand.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/UnauthorizedCommand.java new file mode 100644 index 0000000..3b9fcc0 --- /dev/null +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/commands/UnauthorizedCommand.java @@ -0,0 +1,19 @@ +package me.zinch.Lab7.Server.commands; + +import me.zinch.Lab7.Domain.net.User; +import me.zinch.Lab7.Server.exceptions.CommandActionException; +import me.zinch.Lab7.Server.wrapper.IStorage; + +import java.util.regex.Pattern; + +public abstract class UnauthorizedCommand extends Command { + public UnauthorizedCommand(String name, String description, Pattern pattern) { + super(name, description, pattern); + } + + public UnauthorizedCommand(String name, String description) { + super(name, description); + } + + public abstract String action(Object obj) throws CommandActionException; +} diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/NonExistentCommand.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/NonExistentCommand.java new file mode 100644 index 0000000..c800b96 --- /dev/null +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/NonExistentCommand.java @@ -0,0 +1,21 @@ +package me.zinch.Lab7.Server.exceptions; + +import java.io.IOException; + +public class NonExistentCommand extends IOException { + public NonExistentCommand() { + super("This command doesn't exist"); + } + + public NonExistentCommand(String message) { + super(message); + } + + public NonExistentCommand(String message, Throwable cause) { + super(message, cause); + } + + public NonExistentCommand(Throwable cause) { + super(cause); + } +} diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/UnauthorizedException.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/UnauthorizedException.java new file mode 100644 index 0000000..b344aaa --- /dev/null +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/exceptions/UnauthorizedException.java @@ -0,0 +1,21 @@ +package me.zinch.Lab7.Server.exceptions; + +import java.io.IOException; + +public class UnauthorizedException extends IOException { + public UnauthorizedException() { + super("Error during user validation"); + } + + public UnauthorizedException(String message) { + super(message); + } + + public UnauthorizedException(String message, Throwable cause) { + super(message, cause); + } + + public UnauthorizedException(Throwable cause) { + super(cause); + } +} diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/AuthGuard.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/AuthGuard.java new file mode 100644 index 0000000..404962b --- /dev/null +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/AuthGuard.java @@ -0,0 +1,19 @@ +package me.zinch.Lab7.Server.wrapper; + +import me.zinch.Lab7.Domain.net.User; +import me.zinch.Lab7.Server.db.DbController; +import me.zinch.Lab7.Server.exceptions.CommandActionException; +import me.zinch.Lab7.Server.exceptions.DbExecuteException; +import me.zinch.Lab7.Server.exceptions.UnauthorizedException; + +import java.sql.SQLException; + +public class AuthGuard { + public static void throwIfUserNotValid(User user) throws UnauthorizedException, DbExecuteException { + try { + if (!DbWrapper.isUserExists(user, DbController.getConnection())) throw new UnauthorizedException("Ошибка при валидации пользователя"); + } catch (SQLException e) { + throw new DbExecuteException(); + } + } +} From 9555d619660fea5c6c05ba8a1477691f4ee0af36 Mon Sep 17 00:00:00 2001 From: Ivan Zinchenko Date: Sat, 8 Jun 2024 00:18:58 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BA=D0=B0=D0=B7=20=D0=B2=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D1=86=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B4=D1=83?= =?UTF-8?q?=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/zinch/Lab7/Server/console/Console.java | 2 +- .../Server/{Server => server}/Server.java | 34 +++++++------ .../{Server => server}/ServerBuilder.java | 7 +-- .../zinch/Lab7/Server/wrapper/DbWrapper.java | 19 +++++++ .../Server/wrapper/ProductCollection.java | 49 ++++++++++++------- .../resources/migrations/clearProducts.sql | 2 + .../migrations/getProductsOwners.sql | 3 ++ 7 files changed, 79 insertions(+), 37 deletions(-) rename Lab.Server/src/main/java/me/zinch/Lab7/Server/{Server => server}/Server.java (88%) rename Lab.Server/src/main/java/me/zinch/Lab7/Server/{Server => server}/ServerBuilder.java (87%) create mode 100644 Lab.Server/src/main/resources/migrations/getProductsOwners.sql diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/console/Console.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/console/Console.java index 11c019e..1a68b7d 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/console/Console.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/console/Console.java @@ -2,7 +2,7 @@ package me.zinch.Lab7.Server.console; import me.zinch.Lab7.Domain.exceptions.ValidationException; import me.zinch.Lab7.Server.wrapper.IStorage; -import me.zinch.Lab7.Server.Server.ServerBuilder; +import me.zinch.Lab7.Server.server.ServerBuilder; import me.zinch.Lab7.Server.commands.GetCommand; import me.zinch.Lab7.Server.commands.SystemCommandManager; import me.zinch.Lab7.Server.configs.ServerConfig; diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/server/Server.java similarity index 88% rename from Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java rename to Lab.Server/src/main/java/me/zinch/Lab7/Server/server/Server.java index 322ec0e..a7891b8 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/Server.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/server/Server.java @@ -1,4 +1,4 @@ -package me.zinch.Lab7.Server.Server; +package me.zinch.Lab7.Server.server; import me.zinch.Lab7.Domain.net.BodylessMessage; import me.zinch.Lab7.Domain.net.Message; @@ -6,8 +6,11 @@ import me.zinch.Lab7.Domain.net.MessageBody; import me.zinch.Lab7.Domain.net.MessageType; import me.zinch.Lab7.Domain.net.User; import me.zinch.Lab7.Server.commands.UnauthorizedCommand; +import me.zinch.Lab7.Server.db.DbController; +import me.zinch.Lab7.Server.exceptions.CommandActionException; import me.zinch.Lab7.Server.exceptions.DbExecuteException; import me.zinch.Lab7.Server.exceptions.NonExistentCommand; +import me.zinch.Lab7.Server.exceptions.UnauthorizedException; import me.zinch.Lab7.Server.utils.SHA256; import me.zinch.Lab7.Server.wrapper.AuthGuard; import me.zinch.Lab7.Server.wrapper.IStorage; @@ -27,7 +30,6 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.ServerSocket; import java.net.Socket; -import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -45,7 +47,6 @@ public class Server { serverSocket = new ServerSocket(port); isRunning = true; - if (collection == null) collection = new ProductCollection(new ArrayList<>()); storage = collection; log.info("The server has been assigned to port {}", port); @@ -114,22 +115,25 @@ public class Server { } } - private byte[] createResponse(Message message) throws IOException, DbExecuteException { + private byte[] createResponse(Message message) throws IOException { if (message.getType() == MessageType.HELLO) return serialize(new BodylessMessage(MessageType.HELLO)); var user = (User) message.getUser(); if (user == null) return handleUnauthorizedCommand(message); user.setPassword(SHA256.hash(user.getPassword())); - AuthGuard.throwIfUserNotValid(user); - - return switch (message.getType()) { - case GET -> handleGetCommand((String) message.getBody(), user); - case POST -> handlePostCommand((MessageBody) message.getBody(), user); - default -> { - log.error("Message type not supported"); - yield null; - } - }; + try { + AuthGuard.throwIfUserNotValid(user); + return switch (message.getType()) { + case GET -> handleGetCommand((String) message.getBody(), user); + case POST -> handlePostCommand((MessageBody) message.getBody(), user); + default -> { + log.error("Message type not supported"); + yield null; + } + }; + } catch (IOException | DbExecuteException | CommandActionException e) { + return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage())); + } } private byte[] handleGetCommand(String inputCommand, User user) throws IOException { @@ -163,7 +167,7 @@ public class Server { var action = (UnauthorizedCommand) command.get(); return serialize(new BodylessMessage(MessageType.OK, action.action(body))); - } catch (ClassCastException | NonExistentCommand e) { + } catch (ClassCastException | NonExistentCommand | CommandActionException e) { return serialize(new BodylessMessage(MessageType.ERROR, e.getMessage())); } } diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/ServerBuilder.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/server/ServerBuilder.java similarity index 87% rename from Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/ServerBuilder.java rename to Lab.Server/src/main/java/me/zinch/Lab7/Server/server/ServerBuilder.java index e11d5fc..c98dbff 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/Server/ServerBuilder.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/server/ServerBuilder.java @@ -1,15 +1,17 @@ -package me.zinch.Lab7.Server.Server; +package me.zinch.Lab7.Server.server; import me.zinch.Lab7.Server.wrapper.IStorage; import me.zinch.Lab7.Server.wrapper.ProductCollection; import java.io.IOException; +import java.sql.Connection; import java.util.ArrayList; +import java.util.Set; public class ServerBuilder { private static class Config { private int port = 3000; - private IStorage collection = new ProductCollection(); + private IStorage collection; public int getPort() { return port; @@ -32,7 +34,6 @@ public class ServerBuilder { public ServerBuilder() { config.setPort(3000); - config.setCollection(new ProductCollection(new ArrayList<>())); } private ServerBuilder(Config config) { diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/DbWrapper.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/DbWrapper.java index 6036883..54813a6 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/DbWrapper.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/DbWrapper.java @@ -15,7 +15,9 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class DbWrapper { private static final Logger log = LoggerFactory.getLogger(DbWrapper.class); @@ -196,6 +198,7 @@ public class DbWrapper { public static void clearProducts(User user, Connection connection) throws SQLException { try (var st = connection.prepareStatement(FileReader.readFromResource("migrations/clearProducts.sql"))) { st.setLong(1, getUserId(user, connection)); + st.setLong(2, getUserId(user, connection)); st.executeUpdate(); } catch (SQLException | FileNotFoundException e) { log.error(e.getMessage()); @@ -280,4 +283,20 @@ public class DbWrapper { log.error(e.getMessage()); } } + + public static Map getProductsOwners(Connection connection) throws SQLException { + try (var st = connection.prepareStatement(FileReader.readFromResource("migrations/getProductsOwners.sql"))) { + var productsOwners = new HashMap(); + var rs = st.executeQuery(); + + while (rs.next()) { + productsOwners.put(rs.getLong(1), rs.getString(2)); + } + + return productsOwners; + } catch (SQLException | FileNotFoundException e) { + log.error(e.getMessage()); + throw new SQLException(e); + } + } } diff --git a/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/ProductCollection.java b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/ProductCollection.java index 9cf2f0a..43dfcae 100644 --- a/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/ProductCollection.java +++ b/Lab.Server/src/main/java/me/zinch/Lab7/Server/wrapper/ProductCollection.java @@ -4,6 +4,7 @@ import me.zinch.Lab7.Domain.models.Product; import me.zinch.Lab7.Domain.models.ProductDTO; import me.zinch.Lab7.Domain.net.User; import me.zinch.Lab7.Server.db.DbController; +import me.zinch.Lab7.Server.exceptions.DbConnectionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,7 +16,9 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -26,9 +29,10 @@ import java.util.concurrent.locks.Lock; public class ProductCollection implements IStorage { private static final Logger log = LoggerFactory.getLogger(ProductCollection.class); private TreeSet productList; + private Map productsOwners; private final Lock lock = new ReentrantLock(); - private List fetchProductFromDb(Connection connection) { + private List fetchProducts(Connection connection) { try { return DbWrapper.getProducts(connection); } catch (SQLException | FileNotFoundException e) { @@ -37,25 +41,32 @@ public class ProductCollection implements IStorage { } } - private void Initialize(List list) { + private Map fetchProductsOwners(Connection connection) { + try { + return DbWrapper.getProductsOwners(connection); + } catch (SQLException e) { + log.error(e.getMessage()); + return new HashMap<>(); + } + } + + private void fetchDb() throws DbConnectionException { + productList.clear(); + productList.addAll(fetchProducts(DbController.getConnection())); + productsOwners.clear(); + productsOwners.putAll(fetchProductsOwners(DbController.getConnection())); + } + + public ProductCollection(Connection connection) { productList = new TreeSet<>((o1, o2) -> { var o1Length = Math.sqrt(o1.getCoordinates().getX() * o1.getCoordinates().getX() + o1.getCoordinates().getY() * o1.getCoordinates().getY()); var o2Length = Math.sqrt(o2.getCoordinates().getX() * o2.getCoordinates().getX() + o2.getCoordinates().getY() * o2.getCoordinates().getY()); return Math.toIntExact((long) (o1Length - o2Length)); }); - productList.addAll(list); - } + productsOwners = new HashMap<>(); - public ProductCollection(List list) { - Initialize(list); - } - - public ProductCollection() { - Initialize(new ArrayList<>()); - } - - public ProductCollection(Connection connection) { - Initialize(fetchProductFromDb(connection)); + productList.addAll(fetchProducts(connection)); + productsOwners.putAll(fetchProductsOwners(connection)); } public Product getProductById(Long id) { @@ -83,7 +94,7 @@ public class ProductCollection implements IStorage { lock.lock(); try { var product = DbWrapper.updateProduct(id, productDTO, DbController.getConnection(), user); - fetchProductFromDb(DbController.getConnection()); + fetchDb(); return productDTO.buildProduct(product.getId(), product.getCreationDate()); } finally { lock.unlock(); @@ -119,7 +130,7 @@ public class ProductCollection implements IStorage { lock.lock(); try { DbWrapper.clearProducts(user, DbController.getConnection()); - fetchProductFromDb(DbController.getConnection()); + fetchDb(); } finally { lock.unlock(); } @@ -157,7 +168,7 @@ public class ProductCollection implements IStorage { try { var size = productList.size(); DbWrapper.removeLower(id, DbController.getConnection(), user); - fetchProductFromDb(DbController.getConnection()); + fetchDb(); return size - productList.size(); } finally { lock.unlock(); @@ -203,7 +214,9 @@ public class ProductCollection implements IStorage { public String toString() { lock.lock(); try { - return String.join("\n", productList.stream().map(Product::toString).toList()); + return String.join("\n", productList.stream() + .map(product -> String.format("%s by %s", product.toString(), productsOwners.getOrDefault(product.getId(), "Unknown"))) + .toList()); } finally { lock.unlock(); } diff --git a/Lab.Server/src/main/resources/migrations/clearProducts.sql b/Lab.Server/src/main/resources/migrations/clearProducts.sql index 7dd5fe3..f97041c 100644 --- a/Lab.Server/src/main/resources/migrations/clearProducts.sql +++ b/Lab.Server/src/main/resources/migrations/clearProducts.sql @@ -1,3 +1,5 @@ +DELETE FROM products_owners WHERE "user" = ?; + DELETE FROM products WHERE id IN ( SELECT product FROM products_owners diff --git a/Lab.Server/src/main/resources/migrations/getProductsOwners.sql b/Lab.Server/src/main/resources/migrations/getProductsOwners.sql new file mode 100644 index 0000000..c23ac97 --- /dev/null +++ b/Lab.Server/src/main/resources/migrations/getProductsOwners.sql @@ -0,0 +1,3 @@ +SELECT product, login +FROM products_owners +LEFT JOIN users on products_owners."user" = users.id; \ No newline at end of file