From 2442e5a39fb147713b6d6fed27935e25d5b10089 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:29:47 +0100 Subject: [PATCH 001/104] Add: Bug report template --- .gitlab/issue_templates/bug_report_client.md | 31 ++++++++++++++++++++ .gitlab/issue_templates/bug_report_server.md | 30 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .gitlab/issue_templates/bug_report_client.md create mode 100644 .gitlab/issue_templates/bug_report_server.md diff --git a/.gitlab/issue_templates/bug_report_client.md b/.gitlab/issue_templates/bug_report_client.md new file mode 100644 index 0000000..d1b4373 --- /dev/null +++ b/.gitlab/issue_templates/bug_report_client.md @@ -0,0 +1,31 @@ +## Bug Report + +### Summary + + +### Affected Component + + +### Steps to Reproduce +1. Do this first +2. Then do that next +3. Lastly, see the unexprected error message ... + +### Expected Behavior + + +### Actual Behavior + + +### Stack Trace / Error Message +``` + +``` + +### Possible Cause + + + +/label ~bug + +/label ~client diff --git a/.gitlab/issue_templates/bug_report_server.md b/.gitlab/issue_templates/bug_report_server.md new file mode 100644 index 0000000..46d7572 --- /dev/null +++ b/.gitlab/issue_templates/bug_report_server.md @@ -0,0 +1,30 @@ +## Bug Report + +### Summary + + +### Affected Component + + +### Steps to Reproduce +1. Do this first +2. Then do that next +3. Lastly, see the unexprected error message ... + +### Expected Behavior + + +### Actual Behavior + + +### Stack Trace / Error Message +``` + +``` + +### Possible Cause + + +/label ~bug + +/label ~server From 1106c891aa28360c012572536d0a4239568a679a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:33:43 +0100 Subject: [PATCH 002/104] Add: Feature request template --- .../issue_templates/feature_request_client.md | 27 +++++++++++++++++++ .../issue_templates/feature_request_server.md | 27 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .gitlab/issue_templates/feature_request_client.md create mode 100644 .gitlab/issue_templates/feature_request_server.md diff --git a/.gitlab/issue_templates/feature_request_client.md b/.gitlab/issue_templates/feature_request_client.md new file mode 100644 index 0000000..c654230 --- /dev/null +++ b/.gitlab/issue_templates/feature_request_client.md @@ -0,0 +1,27 @@ +## Feature Request + +### Summary + + +### Motivation / Problem + + +### Description + + +### Affected Components + + + +### Acceptance Criteria + +- [ ] +- [ ] +- [ ] + +### Open Questions / Trade-offs + + +/label ~enhancement + +/label ~client diff --git a/.gitlab/issue_templates/feature_request_server.md b/.gitlab/issue_templates/feature_request_server.md new file mode 100644 index 0000000..38d3377 --- /dev/null +++ b/.gitlab/issue_templates/feature_request_server.md @@ -0,0 +1,27 @@ +## Feature Request + +### Summary + + +### Motivation / Problem + + +### Description + + +### Affected Components + + + +### Acceptance Criteria + +- [ ] +- [ ] +- [ ] + +### Open Questions / Trade-offs + + +/label ~enhancement + +/label ~server From 090d77054c028d79c4413c265d0ed973753ea1af Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:46:25 +0100 Subject: [PATCH 003/104] Add: Protocol schema modification template --- .gitlab/issue_templates/protocol_change.md | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .gitlab/issue_templates/protocol_change.md diff --git a/.gitlab/issue_templates/protocol_change.md b/.gitlab/issue_templates/protocol_change.md new file mode 100644 index 0000000..9846910 --- /dev/null +++ b/.gitlab/issue_templates/protocol_change.md @@ -0,0 +1,42 @@ +## Protocol / API Change + +### Summary + + +### Affected Commands / Responses + + +| Command | Response | Type of Change | Description | +|---------|----------|----------------|-------------| +| | | New / Changed / Removed | | + +### New / Changed Syntax +``` + + +``` + +### Affected Implementation Layers + +- [ ] `Session` +- [ ] `User` or `UserRegistry` +- [ ] `Tokenizer` / `RequestTokenClassifier` +- [ ] `ProtocolParser` +- [ ] `CommandParserDispatcher` + corresponding `CommandParser` +- [ ] `CommandHandler` +- [ ] `Response` hierarchy +- [ ] `GameEngine` or `GameState` +- [ ] Client-side (create your own issue and create link) + +### Migration Strategy + + +### Motivation + + +/label ~protocol + +/label ~server From 0ff4e320ba0862b53609259b70a7f3af2b29dacd Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:48:11 +0100 Subject: [PATCH 004/104] Add: Task template --- .gitlab/issue_templates/task_client.md | 25 +++++++++++++++++++++++++ .gitlab/issue_templates/task_server.md | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 .gitlab/issue_templates/task_client.md create mode 100644 .gitlab/issue_templates/task_server.md diff --git a/.gitlab/issue_templates/task_client.md b/.gitlab/issue_templates/task_client.md new file mode 100644 index 0000000..e5f15a3 --- /dev/null +++ b/.gitlab/issue_templates/task_client.md @@ -0,0 +1,25 @@ +## Task + +### Summary + + +### Context + + +### Affected Components + + +### Dependencies + + +### Definition of Done +- [ ] +- [ ] +- [ ] + +### Notes + + +/label ~task + +/label ~client diff --git a/.gitlab/issue_templates/task_server.md b/.gitlab/issue_templates/task_server.md new file mode 100644 index 0000000..c1a1345 --- /dev/null +++ b/.gitlab/issue_templates/task_server.md @@ -0,0 +1,25 @@ +## Task + +### Summary + + +### Context + + +### Affected Components + + +### Dependencies + + +### Definition of Done +- [ ] +- [ ] +- [ ] + +### Notes + + +/label ~task + +/label ~server From 4df8befd274fe012dabded50208e636ad44ea069 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:51:02 +0100 Subject: [PATCH 005/104] Style: Cleanup and addition of checklist --- .gitlab/issue_templates/protocol_change.md | 3 --- .gitlab/issue_templates/task_client.md | 6 +++--- .gitlab/issue_templates/task_server.md | 6 +++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.gitlab/issue_templates/protocol_change.md b/.gitlab/issue_templates/protocol_change.md index 9846910..ac7ebe9 100644 --- a/.gitlab/issue_templates/protocol_change.md +++ b/.gitlab/issue_templates/protocol_change.md @@ -31,9 +31,6 @@ AFTER: LOGIN USERNAME= PASSWORD= - [ ] `GameEngine` or `GameState` - [ ] Client-side (create your own issue and create link) -### Migration Strategy - - ### Motivation diff --git a/.gitlab/issue_templates/task_client.md b/.gitlab/issue_templates/task_client.md index e5f15a3..f75a1c4 100644 --- a/.gitlab/issue_templates/task_client.md +++ b/.gitlab/issue_templates/task_client.md @@ -9,9 +9,6 @@ ### Affected Components -### Dependencies - - ### Definition of Done - [ ] - [ ] @@ -20,6 +17,9 @@ ### Notes +### Checklist +- [ ] Linked to other issues or branches that must be completed first? + /label ~task /label ~client diff --git a/.gitlab/issue_templates/task_server.md b/.gitlab/issue_templates/task_server.md index c1a1345..e6206d1 100644 --- a/.gitlab/issue_templates/task_server.md +++ b/.gitlab/issue_templates/task_server.md @@ -9,9 +9,6 @@ ### Affected Components -### Dependencies - - ### Definition of Done - [ ] - [ ] @@ -20,6 +17,9 @@ ### Notes +### Checklist +- [ ] Linked to other issues or branches that must be completed first? + /label ~task /label ~server From 918002c8cb725c4fcedd65851263ea2c5e7d474c Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 15:53:58 +0100 Subject: [PATCH 006/104] Remove: Automatic assignment of 'server' label to protocol_change issue --- .gitlab/issue_templates/protocol_change.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab/issue_templates/protocol_change.md b/.gitlab/issue_templates/protocol_change.md index ac7ebe9..6c5d5b2 100644 --- a/.gitlab/issue_templates/protocol_change.md +++ b/.gitlab/issue_templates/protocol_change.md @@ -35,5 +35,3 @@ AFTER: LOGIN USERNAME= PASSWORD= /label ~protocol - -/label ~server From 7b4fd4aeae1e6b80b9b65f235c5c3b423d693be3 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 17:41:45 +0100 Subject: [PATCH 007/104] Add: Make TransportLayer accessible through get-method --- .../cs108/casono/server/network/sessions/Session.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 97e3943..c76ecce 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -47,6 +47,15 @@ public class Session implements Runnable { return this.id; } + /** + * Returns the TransportLayer of this session + * + * @return the transport layer of the session + */ + public TransportLayer getTransport() { + return transport; + } + /** Starts the session thread. */ public void start() { thread.start(); From c10aaf15b538cf774879a4f3fa66858bc7725973 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 18:09:31 +0100 Subject: [PATCH 008/104] Add: Move read logic to SessionReader runnable --- .../server/network/sessions/Session.java | 59 +------------------ .../network/sessions/SessionReader.java | 53 +++++++++++++++++ 2 files changed, 56 insertions(+), 56 deletions(-) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index c76ecce..67a24fd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,24 +1,13 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; -import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; -import java.io.EOFException; import java.io.IOException; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; /** Represents a client session in the network server. */ -public class Session implements Runnable { +public class Session { private SessionId id; - private Thread thread; private TransportLayer transport; - private Logger logger; - private Boolean running; - private EventBus eventBus; /** * Creates a new Session with the given transport and event bus. @@ -27,15 +16,9 @@ public class Session implements Runnable { * @param eventBus the event bus for publishing events * @throws IOException if an I/O error occurs during initialization */ - public Session(TransportLayer transport, EventBus eventBus) throws IOException { + public Session(TransportLayer transport, EventBus eventBus) { this.id = new SessionId(); - this.thread = new Thread(this, "session-" + this.id.value()); this.transport = transport; - this.running = true; - this.eventBus = eventBus; - - this.logger = LogManager.getLogger(Session.class.toString() + id.value()); - this.logger.info("Created new session"); } /** @@ -49,46 +32,10 @@ public class Session implements Runnable { /** * Returns the TransportLayer of this session - * + * * @return the transport layer of the session */ public TransportLayer getTransport() { return transport; } - - /** Starts the session thread. */ - public void start() { - thread.start(); - } - - /** - * Closes the session and its transport. - * - * @throws IOException if an I/O error occurs - */ - public void close() throws IOException { - transport.close(); - this.running = false; - } - - /** Runs the session loop, reading from the transport. */ - @Override - public void run() { - while (running) { - try { - RawPacket rawPacket = transport.read(); - logger.debug("Recieved: {}", rawPacket); - - PrimitiveRequest primitiveRequest = ProtocolParser.parse(rawPacket); - logger.debug("Parsed request to {}", primitiveRequest); - } catch (EOFException e) { - logger.info("Client disconnected"); - eventBus.publish(new DisconnectEvent(id)); - break; - } catch (IOException e) { - e.printStackTrace(); - break; - } - } - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java new file mode 100644 index 0000000..2f8e5fc --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -0,0 +1,53 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; +import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; +import java.io.EOFException; +import java.io.IOException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class SessionReader implements Runnable { + private final Session session; + private final TransportLayer transport; + private final EventBus eventBus; + private final Logger logger; + + public SessionReader(Session session, EventBus eventBus) { + this.session = session; + this.transport = session.getTransport(); + this.eventBus = eventBus; + this.logger = + LogManager.getLogger( + SessionReader.class.toString() + "-" + session.getId().value()); + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + RawPacket rawPacket = transport.read(); + logger.debug("Recieved: {}", rawPacket); + + PrimitiveRequest primitiveRequest = ProtocolParser.parse(rawPacket); + logger.debug("Parsed request to {}", primitiveRequest); + } catch (EOFException e) { + logger.info("Client disconnected"); + eventBus.publish(new DisconnectEvent(session.getId())); + break; + } catch (TokenizerException | ProtocolParserException e) { + logger.trace("Error occured while parsing request", e); + + // TODO: Send error response to client + } catch (IOException e) { + logger.trace("Unexpected exception while reading from transport", e); + } + } + } +} From 355b1cdbd4af258d5a9708389256299a02a5c142 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 18:32:57 +0100 Subject: [PATCH 009/104] Add: Queue to Session --- .../server/network/sessions/Session.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 67a24fd..9837127 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,13 +1,17 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; /** Represents a client session in the network server. */ public class Session { - private SessionId id; - private TransportLayer transport; + private final SessionId id; + private final TransportLayer transport; + private final BlockingQueue responseQueue; /** * Creates a new Session with the given transport and event bus. @@ -19,6 +23,7 @@ public class Session { public Session(TransportLayer transport, EventBus eventBus) { this.id = new SessionId(); this.transport = transport; + this.responseQueue = new ArrayBlockingQueue<>(32); } /** @@ -38,4 +43,13 @@ public class Session { public TransportLayer getTransport() { return transport; } + + /** + * Returns the BlockingQueue of this session + * + * @return the queue containing outgoing responses + */ + public BlockingQueue getResponseQueue() { + return responseQueue; + } } From 8db7986131d392940f8b0157668859e72e092db6 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 18:42:10 +0100 Subject: [PATCH 010/104] Add: PrimitiveResponse as pendant to PrimitiveRequest --- .../casono/server/network/response/PrimitiveResponse.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java new file mode 100644 index 0000000..38a7422 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java @@ -0,0 +1,5 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +public record PrimitiveResponse(SessionId sessionId, int requestId, String payload) {} From ec5ebe5d42cb19f409632e5a85991f80a5e3d2e3 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 18:42:34 +0100 Subject: [PATCH 011/104] Add: SessionWriter to use queue of session and write to transport --- .../network/sessions/SessionWriter.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java new file mode 100644 index 0000000..d886ec8 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java @@ -0,0 +1,38 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; +import java.io.IOException; +import java.util.concurrent.BlockingQueue; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class SessionWriter implements Runnable { + private final TransportLayer transport; + private final BlockingQueue queue; + private final Logger logger; + + public SessionWriter(Session session) { + this.transport = session.getTransport(); + this.queue = session.getResponseQueue(); + this.logger = + LogManager.getLogger( + SessionReader.class.toString() + "-" + session.getId().value()); + } + + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + PrimitiveResponse response = queue.take(); + RawPacket packet = new RawPacket(response.requestId(), response.payload()); + transport.write(packet); + } catch (IOException e) { + logger.trace("Unexpected exception while writing to transport", e); + } catch (InterruptedException e) { + logger.trace("Thread got interrupted", e); + break; + } + } + } +} From 247f16e26e1051d2ea44152ff4ec03c630516ffb Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 19 Mar 2026 19:01:33 +0100 Subject: [PATCH 012/104] Add: SessionHandle to store Session and two worker threads --- .../cs108/casono/server/network/sessions/SessionHandle.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionHandle.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionHandle.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionHandle.java new file mode 100644 index 0000000..a603a8a --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionHandle.java @@ -0,0 +1,4 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; + +/** The SessionHandle stores the session and the two worker threads associated with the session */ +record SessionHandle(Session session, Thread reader, Thread writer) {} From 72da952e5a9baf302f77022f35aac68793bba11a Mon Sep 17 00:00:00 2001 From: Jona Walpert Date: Fri, 20 Mar 2026 11:44:26 +0100 Subject: [PATCH 013/104] Add: Gradle properties to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c29286e..56624a0 100644 --- a/.gitignore +++ b/.gitignore @@ -121,4 +121,5 @@ $RECYCLE.BIN/ .idea ## bin -bin/ \ No newline at end of file +bin/ +gradle.properties \ No newline at end of file From 7713069496195efb1bf365d16ee4445c9eebf852 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:22:47 +0100 Subject: [PATCH 014/104] Add: Make SessionManager use SessionHandle --- .../network/sessions/SessionManager.java | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 6702543..17f06bb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -5,7 +5,7 @@ import java.util.concurrent.ConcurrentHashMap; /** Manages active sessions in the server. */ public class SessionManager { - private Map sessions; + private Map sessions; /** Constructs a new SessionManager. */ public SessionManager() { @@ -17,8 +17,8 @@ public class SessionManager { * * @param session the session to add */ - public void addSession(Session session) { - sessions.put(session.getId(), session); + public void addSession(SessionHandle handle) { + sessions.put(handle.session().getId(), handle); } /** @@ -28,7 +28,13 @@ public class SessionManager { * @return the removed session, or null if not found */ public Session removeSession(SessionId id) { - return sessions.remove(id); + SessionHandle handle = sessions.remove(id); + + if (handle == null) { + return null; + } + + return handle.session(); } /** @@ -38,7 +44,13 @@ public class SessionManager { * @return the removed session, or null if not found */ public Session removeSession(Session session) { - return sessions.remove(session.getId()); + SessionHandle handle = sessions.remove(session.getId()); + + if (handle == null) { + return null; + } + + return handle.session(); } /** @@ -48,6 +60,12 @@ public class SessionManager { * @return the session with the specified ID, or null if not found */ public Session getSessionById(SessionId id) { - return sessions.get(id); + SessionHandle handle = sessions.get(id); + + if (handle == null) { + return null; + } + + return handle.session(); } } From 11a7f0036c1699f0a2d0f079be95ed5b095ab783 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:28:33 +0100 Subject: [PATCH 015/104] Add: create and disconnect methods to SessionManager --- .../network/sessions/SessionManager.java | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 17f06bb..6dfe245 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -1,24 +1,73 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; +import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; /** Manages active sessions in the server. */ public class SessionManager { private Map sessions; + private final EventBus eventBus; + private final Logger logger; /** Constructs a new SessionManager. */ - public SessionManager() { + public SessionManager(EventBus eventBus) { this.sessions = new ConcurrentHashMap<>(); + this.eventBus = eventBus; + this.logger = LogManager.getLogger(SessionManager.class); } /** - * Adds a session to the manager. - * - * @param session the session to add + * Create new Session from provided transport. + * + *

Will create both worker threads and start them. + * + * @param transport to create session from + * @return newly created session */ - public void addSession(SessionHandle handle) { - sessions.put(handle.session().getId(), handle); + public Session create(TransportLayer transport) { + Session session = new Session(transport, eventBus); + + SessionReader reader = new SessionReader(session, eventBus); + Thread readerThread = new Thread(reader, "session-" + session.getId().value() + "-reader"); + readerThread.start(); + + SessionWriter writer = new SessionWriter(session); + Thread writerThread = new Thread(writer, "session-" + session.getId().value() + "-writer"); + writerThread.start(); + + SessionHandle handle = new SessionHandle(session, readerThread, writerThread); + sessions.put(session.getId(), handle); + logger.debug("Created new session {}", session.getId().value()); + return session; + } + + /** + * Disconnect specified client + * + *

WARNING: Client will be uninformed about disconnect. Use with caution. + * + * @param id of the client to disconnect + */ + public void disconnect(SessionId id) { + SessionHandle handle = sessions.get(id); + if (handle == null) { + logger.warn("Requested to disconnect client with id {}. Failed as client is not found", id.value()); + return; + } + logger.debug("Disconnecting session {}", id.value()); + + handle.reader().interrupt(); + handle.writer().interrupt(); + try { + handle.session().getTransport().close(); + } catch (IOException e) { + logger.trace("Unexpected exception while closing transport", e); + } } /** From 761cf4a760e08cd171a2f5794b090dfcecef0be7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:30:06 +0100 Subject: [PATCH 016/104] Add: DisconnectEvent handler function to SessionManager --- .../server/network/sessions/SessionManager.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 6dfe245..013680b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; @@ -70,6 +72,17 @@ public class SessionManager { } } + /** + * Handler for the DisconnectEvent + * + * @param id of the session that disconnected + */ + public void onDisconnect(DisconnectEvent event) { + logger.debug("Recieved DisconnectEvent event for session {}", event.sessionId().value()); + + disconnect(event.sessionId()); + } + /** * Removes a session by its ID. * From 35da4d27700ab5b000118ccd111625106655b028 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:30:38 +0100 Subject: [PATCH 017/104] Add: Make NetworkManager use SessionManager to create session --- .../dmi/dbis/cs108/casono/server/network/NetworkManager.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index ad2e5b3..4833d61 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -2,7 +2,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport; import java.io.IOException; @@ -61,9 +60,7 @@ public class NetworkManager implements Runnable { logger.debug("Accepted connection from {}", clientSocket.getRemoteSocketAddress()); - Session session = new Session(new TcpTransport(clientSocket), eventBus); - sessionManager.addSession(session); - session.start(); + sessionManager.create(new TcpTransport(clientSocket)); } } catch (IOException e) { From 699b9053eb1c203a99b4bcefec08ba93b39df8b2 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:31:26 +0100 Subject: [PATCH 018/104] Add: Instantiate SessionManager with provided eventManager and correct DisconnectEvent handler --- .../ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index d44df55..ddb1138 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -26,9 +26,9 @@ public class ServerApp { logger.info("Starting server at port {}", port); EventBus eventBus = new EventBus(); - SessionManager sessionManager = new SessionManager(); + SessionManager sessionManager = new SessionManager(eventBus); eventBus.subscribe( - DisconnectEvent.class, event -> sessionManager.removeSession(event.sessionId())); + DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); NetworkManager networkManager = new NetworkManager(port, sessionManager, eventBus); UserRegistry userRegistry = new UserRegistry(); From 9e8ea37e882ef9487a85e7478491f75cfb2014ad Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:37:46 +0100 Subject: [PATCH 019/104] Remove: DisconnectEvent handler from NetworkManager --- .../casono/server/network/NetworkManager.java | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java index 4833d61..d9382a4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/NetworkManager.java @@ -1,7 +1,5 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network; -import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; -import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport; import java.io.IOException; @@ -17,23 +15,19 @@ public class NetworkManager implements Runnable { private Thread thread; private Boolean running; private SessionManager sessionManager; - private EventBus eventBus; /** * Creates a new NetworkManager with the given port, session manager, and event bus. * * @param port the port to listen on * @param sessionManager the session manager to use - * @param eventBus the event bus for events */ - public NetworkManager(Integer port, SessionManager sessionManager, EventBus eventBus) { + public NetworkManager(Integer port, SessionManager sessionManager) { this.port = port; this.logger = LogManager.getLogger(NetworkManager.class); this.thread = new Thread(this, "networkManager"); this.running = true; this.sessionManager = sessionManager; - this.eventBus = eventBus; - this.eventBus.subscribe(DisconnectEvent.class, event -> clientDisconnected(event)); } /** Starts the internal thread to accept new connections. */ @@ -42,15 +36,6 @@ public class NetworkManager implements Runnable { thread.start(); } - /** - * Handles client disconnection events. - * - * @param event the disconnect event - */ - public void clientDisconnected(DisconnectEvent event) { - logger.info("Session {} disconnected", event.sessionId().value()); - } - /** Runs the network manager loop, accepting connections. */ @Override public void run() { From 107870ff78128f8525a0c47bb17b9587d483fab7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:46:26 +0100 Subject: [PATCH 020/104] Remove: eventBus argument from NetworkManager creation --- .../java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index ddb1138..985b60a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -29,7 +29,7 @@ public class ServerApp { SessionManager sessionManager = new SessionManager(eventBus); eventBus.subscribe( DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); - NetworkManager networkManager = new NetworkManager(port, sessionManager, eventBus); + NetworkManager networkManager = new NetworkManager(port, sessionManager); UserRegistry userRegistry = new UserRegistry(); eventBus.subscribe( From 2ed7ae4e5d0fb5b8490dc6c43fdf7f7f1909dbb3 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:47:01 +0100 Subject: [PATCH 021/104] Fix: Replace logging level 'trace' with 'error' and 'warn' --- .../cs108/casono/server/network/sessions/SessionManager.java | 2 +- .../cs108/casono/server/network/sessions/SessionReader.java | 4 ++-- .../cs108/casono/server/network/sessions/SessionWriter.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 013680b..efe43ca 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -68,7 +68,7 @@ public class SessionManager { try { handle.session().getTransport().close(); } catch (IOException e) { - logger.trace("Unexpected exception while closing transport", e); + logger.error("Unexpected exception while closing transport", e); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 2f8e5fc..45e83a4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -42,11 +42,11 @@ public class SessionReader implements Runnable { eventBus.publish(new DisconnectEvent(session.getId())); break; } catch (TokenizerException | ProtocolParserException e) { - logger.trace("Error occured while parsing request", e); + logger.error("Error occured while parsing request", e); // TODO: Send error response to client } catch (IOException e) { - logger.trace("Unexpected exception while reading from transport", e); + logger.error("Unexpected exception while reading from transport", e); } } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java index d886ec8..714745c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java @@ -28,9 +28,9 @@ public class SessionWriter implements Runnable { RawPacket packet = new RawPacket(response.requestId(), response.payload()); transport.write(packet); } catch (IOException e) { - logger.trace("Unexpected exception while writing to transport", e); + logger.error("Unexpected exception while writing to transport", e); } catch (InterruptedException e) { - logger.trace("Thread got interrupted", e); + logger.warn("Thread got interrupted", e); break; } } From f79f7f0ae2aeae24335348d71dc24139c8cb04b9 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 16:56:03 +0100 Subject: [PATCH 022/104] Add: Useful information to log statement to ease debugging --- .../cs108/casono/server/network/sessions/SessionReader.java | 5 +++-- .../cs108/casono/server/network/sessions/SessionWriter.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 45e83a4..7c2a6c7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -31,8 +31,9 @@ public class SessionReader implements Runnable { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { + RawPacket rawPacket = null; try { - RawPacket rawPacket = transport.read(); + rawPacket = transport.read(); logger.debug("Recieved: {}", rawPacket); PrimitiveRequest primitiveRequest = ProtocolParser.parse(rawPacket); @@ -42,7 +43,7 @@ public class SessionReader implements Runnable { eventBus.publish(new DisconnectEvent(session.getId())); break; } catch (TokenizerException | ProtocolParserException e) { - logger.error("Error occured while parsing request", e); + logger.error("Error occured while parsing request. RawPacket: {}", rawPacket, e); // TODO: Send error response to client } catch (IOException e) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java index 714745c..7d85fec 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java @@ -23,12 +23,13 @@ public class SessionWriter implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { + RawPacket packet = null; try { PrimitiveResponse response = queue.take(); - RawPacket packet = new RawPacket(response.requestId(), response.payload()); + packet = new RawPacket(response.requestId(), response.payload()); transport.write(packet); } catch (IOException e) { - logger.error("Unexpected exception while writing to transport", e); + logger.error("Unexpected exception while writing to transport. RawPacket: {}", packet, e); } catch (InterruptedException e) { logger.warn("Thread got interrupted", e); break; From b19e923356fbb96dad3f985e334a3723269e5ae6 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 17:09:59 +0100 Subject: [PATCH 023/104] Style: Magic number, linelength and trailing whitespace --- .../dbis/cs108/casono/server/ServerApp.java | 3 +-- .../server/network/sessions/Session.java | 4 +++- .../network/sessions/SessionManager.java | 23 ++++++++++--------- .../network/sessions/SessionWriter.java | 5 +++- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 985b60a..126b341 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -27,8 +27,7 @@ public class ServerApp { EventBus eventBus = new EventBus(); SessionManager sessionManager = new SessionManager(eventBus); - eventBus.subscribe( - DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); + eventBus.subscribe(DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); NetworkManager networkManager = new NetworkManager(port, sessionManager); UserRegistry userRegistry = new UserRegistry(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 9837127..84f4489 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -13,6 +13,8 @@ public class Session { private final TransportLayer transport; private final BlockingQueue responseQueue; + private final int RESPOND_QUEUE_SIZE = 32; + /** * Creates a new Session with the given transport and event bus. * @@ -23,7 +25,7 @@ public class Session { public Session(TransportLayer transport, EventBus eventBus) { this.id = new SessionId(); this.transport = transport; - this.responseQueue = new ArrayBlockingQueue<>(32); + this.responseQueue = new ArrayBlockingQueue<>(RESPOND_QUEUE_SIZE); } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index efe43ca..c81c119 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -1,15 +1,14 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; -import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; - /** Manages active sessions in the server. */ public class SessionManager { private Map sessions; @@ -25,9 +24,9 @@ public class SessionManager { /** * Create new Session from provided transport. - * - *

Will create both worker threads and start them. - * + * + *

Will create both worker threads and start them. + * * @param transport to create session from * @return newly created session */ @@ -50,15 +49,17 @@ public class SessionManager { /** * Disconnect specified client - * - *

WARNING: Client will be uninformed about disconnect. Use with caution. - * + * + *

WARNING: Client will be uninformed about disconnect. Use with caution. + * * @param id of the client to disconnect */ public void disconnect(SessionId id) { SessionHandle handle = sessions.get(id); if (handle == null) { - logger.warn("Requested to disconnect client with id {}. Failed as client is not found", id.value()); + logger.warn( + "Requested to disconnect client with id {}. Failed as client is not found", + id.value()); return; } logger.debug("Disconnecting session {}", id.value()); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java index 7d85fec..e5c3e78 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java @@ -29,7 +29,10 @@ public class SessionWriter implements Runnable { packet = new RawPacket(response.requestId(), response.payload()); transport.write(packet); } catch (IOException e) { - logger.error("Unexpected exception while writing to transport. RawPacket: {}", packet, e); + logger.error( + "Unexpected exception while writing to transport. RawPacket: {}", + packet, + e); } catch (InterruptedException e) { logger.warn("Thread got interrupted", e); break; From c6833b71e84d10227bdc375bd8f5e1367715bff8 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 17:12:55 +0100 Subject: [PATCH 024/104] Style: Add missing 'static' keyword to static variable --- .../dmi/dbis/cs108/casono/server/network/sessions/Session.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 84f4489..0a9be66 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -12,8 +12,7 @@ public class Session { private final SessionId id; private final TransportLayer transport; private final BlockingQueue responseQueue; - - private final int RESPOND_QUEUE_SIZE = 32; + private static final int RESPOND_QUEUE_SIZE = 32; /** * Creates a new Session with the given transport and event bus. From 0bb5a1e940c86a85bd5f330b5197362f9d2c450f Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 17:21:36 +0100 Subject: [PATCH 025/104] Fix: Remove session requested to be disconnected from sessions map --- .../cs108/casono/server/network/sessions/SessionManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index c81c119..9ad41cd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -55,7 +55,7 @@ public class SessionManager { * @param id of the client to disconnect */ public void disconnect(SessionId id) { - SessionHandle handle = sessions.get(id); + SessionHandle handle = sessions.remove(id); if (handle == null) { logger.warn( "Requested to disconnect client with id {}. Failed as client is not found", From 94fcd882231f3100d4e04ead1986ed822b174e6d Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 17:31:44 +0100 Subject: [PATCH 026/104] Fix: Avoid Race condition in create method of SessionManager --- .../network/sessions/SessionManager.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 9ad41cd..b78439b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -32,18 +32,19 @@ public class SessionManager { */ public Session create(TransportLayer transport) { Session session = new Session(transport, eventBus); - SessionReader reader = new SessionReader(session, eventBus); - Thread readerThread = new Thread(reader, "session-" + session.getId().value() + "-reader"); - readerThread.start(); - SessionWriter writer = new SessionWriter(session); - Thread writerThread = new Thread(writer, "session-" + session.getId().value() + "-writer"); - writerThread.start(); - SessionHandle handle = new SessionHandle(session, readerThread, writerThread); - sessions.put(session.getId(), handle); - logger.debug("Created new session {}", session.getId().value()); + Thread readerThread = Thread.ofVirtual() + .name("session-" + session.getId().value() + "-reader") + .unstarted(reader); + Thread writerThread = Thread.ofVirtual() + .name("session-" + session.getId().value() + "-writer") + .unstarted(writer); + + sessions.put(session.getId(), new SessionHandle(session, readerThread, writerThread)); + readerThread.start(); + writerThread.start(); return session; } From e2e01addaa262c5b4ce33b0c16775e0d7780876b Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Fri, 20 Mar 2026 17:32:16 +0100 Subject: [PATCH 027/104] Fix: Leak of SessionManager by removing both removeSession method --- .../network/sessions/SessionManager.java | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index b78439b..2ff6e38 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -85,38 +85,6 @@ public class SessionManager { disconnect(event.sessionId()); } - /** - * Removes a session by its ID. - * - * @param id the ID of the session to remove - * @return the removed session, or null if not found - */ - public Session removeSession(SessionId id) { - SessionHandle handle = sessions.remove(id); - - if (handle == null) { - return null; - } - - return handle.session(); - } - - /** - * Removes the specified session. - * - * @param session the session to remove - * @return the removed session, or null if not found - */ - public Session removeSession(Session session) { - SessionHandle handle = sessions.remove(session.getId()); - - if (handle == null) { - return null; - } - - return handle.session(); - } - /** * Retrieves a session by its ID. * From f3703e4dbdcbb7c453273b594d070c5ccffe30c7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 23 Mar 2026 10:28:28 +0100 Subject: [PATCH 028/104] Build: Bumb google-java-format version from '1.25.2' to '1.35.0' --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e126d6d..a7f3f9e 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,7 @@ checkstyle { spotless { java { - googleJavaFormat('1.25.2').aosp() + googleJavaFormat('1.35.0').aosp() importOrder() removeUnusedImports() trimTrailingWhitespace() From 0f58b4e9981d38f6059fd039c395adb3c2811838 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 23 Mar 2026 15:44:58 +0100 Subject: [PATCH 029/104] Add: Encodable interface as lowest instance --- .../dbis/cs108/casono/server/network/response/Encodable.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java new file mode 100644 index 0000000..af4d231 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java @@ -0,0 +1,5 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +public interface Encodable { + String encode(); +} From eb63f6d39b91b4170e38aacabafde5e732e9dd07 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 23 Mar 2026 15:45:44 +0100 Subject: [PATCH 030/104] Add: Base classes for all responses --- .../network/response/ErrorResponse.java | 32 +++++++++++++++++++ .../server/network/response/Response.java | 16 ++++++++++ .../network/response/SuccessResponse.java | 23 +++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java new file mode 100644 index 0000000..801667e --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java @@ -0,0 +1,32 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +public class ErrorResponse extends Response { + private final String code; + private final String message; + + public ErrorResponse( + SessionId sessionId, int requestId, String errorCode, String errorMessage) { + this.sessionId = sessionId; + this.requestId = requestId; + this.code = errorCode; + this.message = errorMessage; + } + + public ErrorResponse(SessionId sessionId, int requestId, String errorCode) { + this.sessionId = sessionId; + this.requestId = requestId; + this.code = errorCode; + this.message = null; + } + + @Override + public String encode() { + if (message != null && !message.isEmpty()) { + return "-ERR CODE=" + code + " MSG=" + message; + } else { + return "-ERR CODE=" + code; + } + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java new file mode 100644 index 0000000..f9c0f20 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java @@ -0,0 +1,16 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +public abstract class Response implements Encodable { + protected SessionId sessionId; + protected int requestId; + + public SessionId getSessionId() { + return sessionId; + } + + public int getRequestId() { + return requestId; + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java new file mode 100644 index 0000000..e9f9f2d --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java @@ -0,0 +1,23 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +public abstract class SuccessResponse extends Response { + public SuccessResponse(SessionId sessionId, int requestId) { + this.sessionId = sessionId; + this.requestId = requestId; + } + + public final String encode() { + String payload = payload(); + if (payload.isBlank()) { + return "+OK"; + } else { + return "+OK " + payload; + } + } + + protected String payload() { + return ""; + } +} From bcfbe065321f7861f8f19ee84784469bc3387d1d Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 12:19:25 +0100 Subject: [PATCH 031/104] Add: ResponseNode and implementations to store body of response --- .../casono/server/network/response/ResponseBlock.java | 5 +++++ .../cs108/casono/server/network/response/ResponseNode.java | 3 +++ .../casono/server/network/response/ResponseParameter.java | 7 +++++++ 3 files changed, 15 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java new file mode 100644 index 0000000..868b7ee --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java @@ -0,0 +1,5 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import java.util.List; + +public record ResponseBlock(String tag, List children) implements ResponseNode {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java new file mode 100644 index 0000000..ea22d0a --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java @@ -0,0 +1,3 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +public interface ResponseNode {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java new file mode 100644 index 0000000..4d04293 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +public record ResponseParameter(String key, Object value) implements ResponseNode { + public String rawValue() { + return value.toString(); + } +} From e7c9063a5d74523f39722e8d6972462371b13222 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 12:33:36 +0100 Subject: [PATCH 032/104] Remove: Encodable as encode-method is no longer used --- .../dbis/cs108/casono/server/network/response/Encodable.java | 5 ----- .../dbis/cs108/casono/server/network/response/Response.java | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java deleted file mode 100644 index af4d231..0000000 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Encodable.java +++ /dev/null @@ -1,5 +0,0 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; - -public interface Encodable { - String encode(); -} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java index f9c0f20..c2274ad 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java @@ -2,7 +2,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; -public abstract class Response implements Encodable { +public abstract class Response { protected SessionId sessionId; protected int requestId; From 796827cbb4e57860d167ebffce3176affa92f0a7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 12:52:35 +0100 Subject: [PATCH 033/104] Add: ResponseBody and ResponseBodyBuilder classes for building response body --- .../server/network/response/ResponseBody.java | 19 ++++++++++++++ .../network/response/ResponseBodyBuilder.java | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java new file mode 100644 index 0000000..7e75f59 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java @@ -0,0 +1,19 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import java.util.List; + +public class ResponseBody { + private final List nodes; + + ResponseBody(List nodes) { + this.nodes = List.copyOf(nodes); + } + + public static ResponseBodyBuilder builder() { + return new ResponseBodyBuilder(); + } + + public List nodes() { + return nodes; + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java new file mode 100644 index 0000000..e8a8329 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java @@ -0,0 +1,25 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class ResponseBodyBuilder { + private final List nodes = new ArrayList<>(); + + public ResponseBodyBuilder param(String key, Object value) { + nodes.add(new ResponseParameter(key, value)); + return this; + } + + public ResponseBodyBuilder block(String tag, Consumer content) { + ResponseBodyBuilder childBuilder = new ResponseBodyBuilder(); + content.accept(childBuilder); + nodes.add(new ResponseBlock(tag, childBuilder.build().nodes())); + return this; + } + + public ResponseBody build() { + return new ResponseBody(nodes); + } +} From 02c82c4e953fb59084065613a11f84325fe8802f Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 13:11:25 +0100 Subject: [PATCH 034/104] Refactor: Responses to use new ResponseBody --- .../network/response/ErrorResponse.java | 30 +++++-------------- .../server/network/response/Response.java | 17 +++++++++-- .../network/response/SuccessResponse.java | 19 ++++-------- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java index 801667e..a26244b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java @@ -3,30 +3,16 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; public class ErrorResponse extends Response { - private final String code; - private final String message; - - public ErrorResponse( - SessionId sessionId, int requestId, String errorCode, String errorMessage) { - this.sessionId = sessionId; - this.requestId = requestId; - this.code = errorCode; - this.message = errorMessage; - } - - public ErrorResponse(SessionId sessionId, int requestId, String errorCode) { - this.sessionId = sessionId; - this.requestId = requestId; - this.code = errorCode; - this.message = null; + public ErrorResponse(SessionId sessionId, int requestId, String errorCode, String errorMessage) { + super(sessionId, requestId, ResponseBody.builder() + .param("CODE", errorCode) + .param("MSG", errorMessage) + .build() + ); } @Override - public String encode() { - if (message != null && !message.isEmpty()) { - return "-ERR CODE=" + code + " MSG=" + message; - } else { - return "-ERR CODE=" + code; - } + public String prefix() { + return "-ERR"; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java index c2274ad..b42e7af 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java @@ -3,8 +3,17 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; public abstract class Response { - protected SessionId sessionId; - protected int requestId; + private final SessionId sessionId; + private final int requestId; + private final ResponseBody body; + + protected Response(SessionId sessionId, int requestId, ResponseBody body) { + this.sessionId = sessionId; + this.requestId = requestId; + this.body = body; + } + + public abstract String prefix(); public SessionId getSessionId() { return sessionId; @@ -13,4 +22,8 @@ public abstract class Response { public int getRequestId() { return requestId; } + + public ResponseBody getBody() { + return body; + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java index e9f9f2d..dae5308 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java @@ -3,21 +3,12 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; public abstract class SuccessResponse extends Response { - public SuccessResponse(SessionId sessionId, int requestId) { - this.sessionId = sessionId; - this.requestId = requestId; + protected SuccessResponse(SessionId sessionId, int requestId, ResponseBody body) { + super(sessionId, requestId, body); } - public final String encode() { - String payload = payload(); - if (payload.isBlank()) { - return "+OK"; - } else { - return "+OK " + payload; - } - } - - protected String payload() { - return ""; + @Override + public final String prefix() { + return "+OK"; } } From a281f747895311a4aba34ce86e96a1c8444911ad Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 13:39:06 +0100 Subject: [PATCH 035/104] Add: ResponseEncoder to encode Response to PrimitiveResponse --- .../network/response/ResponseEncoder.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java new file mode 100644 index 0000000..873ee66 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java @@ -0,0 +1,57 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +public class ResponseEncoder { + private static final String INDENT = "\t"; + private static final String NEWLINE = "\n"; + + public static PrimitiveResponse encode(Response response) { + StringBuilder sb = new StringBuilder(); + sb.append(response.prefix()); + + for (ResponseNode node : response.getBody().nodes()) { + sb.append(NEWLINE); + encodeNode(node, sb, 1); + } + + sb.append(NEWLINE).append("END"); + + return new PrimitiveResponse( + response.getSessionId(), response.getRequestId(), sb.toString()); + } + + private static void encodeNode(ResponseNode node, StringBuilder sb, int depth) { + if (node instanceof ResponseParameter param) { + encodeParameter(param, sb, depth); + } else if (node instanceof ResponseBlock block) { + encodeBlock(block, sb, depth); + } + } + + private static void encodeParameter(ResponseParameter param, StringBuilder sb, int depth) { + sb.append(INDENT.repeat(depth)); + sb.append(param.key()); + sb.append("="); + sb.append(maskIfNeeded(param.value().toString())); + } + + private static void encodeBlock(ResponseBlock block, StringBuilder sb, int depth) { + sb.append(INDENT.repeat(depth)); + sb.append(block.tag()); + + for (ResponseNode child : block.children()) { + sb.append(NEWLINE); + encodeNode(child, sb, depth + 1); + } + + sb.append(NEWLINE); + sb.append(INDENT.repeat(depth)); + sb.append("END"); + } + + private static String maskIfNeeded(String value) { + if (value.contains(" ")) { + return "'" + value + "'"; + } + return value; + } +} From d0b431b65022f849dd7ecb7272ebafed1b7f6dae Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 13:40:34 +0100 Subject: [PATCH 036/104] Fix: Escape single quote when masking string --- .../casono/server/network/response/ResponseEncoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java index 873ee66..bc66aad 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java @@ -49,8 +49,9 @@ public class ResponseEncoder { } private static String maskIfNeeded(String value) { - if (value.contains(" ")) { - return "'" + value + "'"; + if (value.contains(" ") || value.contains("'")) { + String escaped = value.replace("'", "\\'"); + return "'" + escaped + "'"; } return value; } From 676216d291ce1e113d4195a5613bb100bef4f1e2 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 13:49:24 +0100 Subject: [PATCH 037/104] Add: ResponseDispatcher for handling response dispatching --- .../network/response/ResponseDispatcher.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java new file mode 100644 index 0000000..184cd78 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java @@ -0,0 +1,18 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; + +public class ResponseDispatcher { + private final SessionManager sessionManager; + + public ResponseDispatcher(SessionManager sessionManager) { + this.sessionManager = sessionManager; + } + + public void dispatch(Response response) throws InterruptedException { + PrimitiveResponse primitiveResponse = ResponseEncoder.encode(response); + Session session = sessionManager.getSessionById(response.getSessionId()); + session.getResponseQueue().put(primitiveResponse); + } +} From 696542003fa9535f883c396fab064e5ae3f68d13 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 14:33:46 +0100 Subject: [PATCH 038/104] Add: Detailed JavaDoc documentation for response related components Disclaimer: The docstrings have been written with Copilot but fact-checked by me. --- .../network/response/ErrorResponse.java | 28 ++++++++++--- .../network/response/PrimitiveResponse.java | 7 ++++ .../server/network/response/Response.java | 31 +++++++++++++- .../network/response/ResponseBlock.java | 7 ++++ .../server/network/response/ResponseBody.java | 21 ++++++++++ .../network/response/ResponseBodyBuilder.java | 26 ++++++++++++ .../network/response/ResponseDispatcher.java | 18 +++++++++ .../network/response/ResponseEncoder.java | 40 +++++++++++++++++++ .../server/network/response/ResponseNode.java | 5 +++ .../network/response/ResponseParameter.java | 16 ++++++++ .../network/response/SuccessResponse.java | 20 ++++++++++ 11 files changed, 212 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java index a26244b..602181b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java @@ -2,15 +2,31 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; +/** Response representing an error outcome for a client's request. */ public class ErrorResponse extends Response { - public ErrorResponse(SessionId sessionId, int requestId, String errorCode, String errorMessage) { - super(sessionId, requestId, ResponseBody.builder() - .param("CODE", errorCode) - .param("MSG", errorMessage) - .build() - ); + /** + * Construct an error response with a code and message. + * + * @param sessionId the target session id + * @param requestId the originating request id + * @param errorCode a short error code identifying the failure + * @param errorMessage a human readable error message + */ + public ErrorResponse( + SessionId sessionId, int requestId, String errorCode, String errorMessage) { + super( + sessionId, + requestId, + ResponseBody.builder().param("CODE", errorCode).param("MSG", errorMessage).build()); } + /** + * {@inheritDoc} + * + *

This implementation returns the fixed {@code -ERR} prefix. + * + * @return the {@code -ERR} prefix + */ @Override public String prefix() { return "-ERR"; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java index 38a7422..1ef7a6a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java @@ -2,4 +2,11 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; +/** + * Immutable transport record representing an encoded response ready for delivery to a session. + * + * @param sessionId the target session id + * @param requestId the originating request id + * @param payload the serialized response payload + */ public record PrimitiveResponse(SessionId sessionId, int requestId, String payload) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java index b42e7af..8a3cf96 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java @@ -2,28 +2,57 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; +/** Abstract base class for all server responses sent to clients. */ public abstract class Response { private final SessionId sessionId; private final int requestId; private final ResponseBody body; + /** + * Create a new {@code Response}. + * + * @param sessionId the id of the session this response targets + * @param requestId the request identifier this response corresponds to + * @param body the structured response body + */ protected Response(SessionId sessionId, int requestId, ResponseBody body) { this.sessionId = sessionId; this.requestId = requestId; this.body = body; } + /** + * Returns the protocol prefix for this response (for example {@code "+OK"} or {@code "-ERR"}). + * + * @return the response prefix string used by the encoder + */ public abstract String prefix(); + /** + * Returns the session id that should receive this response. + * + * @return the target {@link SessionId} + */ public SessionId getSessionId() { return sessionId; } + /** + * Returns the request identifier associated with this response. + * + * @return the numeric request id + */ public int getRequestId() { return requestId; } + /** + * Returns the immutable {@link ResponseBody} that carries the structured payload for this + * response. + * + * @return the response body + */ public ResponseBody getBody() { - return body; + return body; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java index 868b7ee..075abaf 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java @@ -2,4 +2,11 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import java.util.List; +/** + * A block node that contains a tag and a list of child {@link ResponseNode} elements. Blocks can be + * nested to build hierarchical response bodies. + * + * @param tag the block tag + * @param children the child nodes contained in this block + */ public record ResponseBlock(String tag, List children) implements ResponseNode {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java index 7e75f59..8c52ffc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java @@ -2,17 +2,38 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import java.util.List; +/** + * Immutable container for the structured content of a {@link Response}. + * + *

A {@code ResponseBody} holds an ordered list of {@link ResponseNode} items (parameters and + * blocks). Use {@link #builder()} to construct instances. + */ public class ResponseBody { private final List nodes; + /** + * Package-private constructor used by {@link ResponseBodyBuilder}. + * + * @param nodes the list of response nodes to include in this body + */ ResponseBody(List nodes) { this.nodes = List.copyOf(nodes); } + /** + * Create a new {@link ResponseBodyBuilder} for assembling a response body. + * + * @return a fresh builder instance + */ public static ResponseBodyBuilder builder() { return new ResponseBodyBuilder(); } + /** + * Returns the ordered list of {@link ResponseNode} elements contained in this body. + * + * @return an immutable list of nodes + */ public List nodes() { return nodes; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java index e8a8329..f6491b0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java @@ -4,14 +4,35 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +/** + * Builder for {@link ResponseBody} instances. + * + *

Provides methods to append parameter nodes and nested blocks and to produce an immutable + * {@link ResponseBody} via {@link #build()}. + */ public class ResponseBodyBuilder { private final List nodes = new ArrayList<>(); + /** + * Add a key/value parameter to the response body under construction. + * + * @param key the parameter name + * @param value the parameter value (will be converted to string when encoded) + * @return this builder for fluent chaining + */ public ResponseBodyBuilder param(String key, Object value) { nodes.add(new ResponseParameter(key, value)); return this; } + /** + * Add a nested block with the given tag. The provided consumer receives a child builder to + * populate the block content. + * + * @param tag the block tag + * @param content consumer that appends child nodes to the block + * @return this builder for fluent chaining + */ public ResponseBodyBuilder block(String tag, Consumer content) { ResponseBodyBuilder childBuilder = new ResponseBodyBuilder(); content.accept(childBuilder); @@ -19,6 +40,11 @@ public class ResponseBodyBuilder { return this; } + /** + * Build an immutable {@link ResponseBody} from the accumulated nodes. + * + * @return a new {@link ResponseBody} + */ public ResponseBody build() { return new ResponseBody(nodes); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java index 184cd78..57b9181 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java @@ -3,13 +3,31 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; +/** + * Helper that dispatches {@link Response} instances to the corresponding {@link Session} by + * encoding them and enqueuing the resulting {@link PrimitiveResponse} into the session's response + * queue. + */ public class ResponseDispatcher { private final SessionManager sessionManager; + /** + * Create a dispatcher bound to a {@link SessionManager}. + * + * @param sessionManager manager used to resolve sessions + */ public ResponseDispatcher(SessionManager sessionManager) { this.sessionManager = sessionManager; } + /** + * Encode the given {@link Response} and enqueue the resulting {@link PrimitiveResponse} into + * the target session's response queue. + * + * @param response the response to dispatch + * @throws InterruptedException if the thread is interrupted while waiting to enqueue the + * primitive response + */ public void dispatch(Response response) throws InterruptedException { PrimitiveResponse primitiveResponse = ResponseEncoder.encode(response); Session session = sessionManager.getSessionById(response.getSessionId()); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java index bc66aad..dbe8d12 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java @@ -1,9 +1,20 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +/** + * Utility responsible for encoding a {@link Response} into a protocol payload string and wrapping + * it into a {@link PrimitiveResponse} suitable for transmission. + */ public class ResponseEncoder { private static final String INDENT = "\t"; private static final String NEWLINE = "\n"; + /** + * Encode a {@link Response} into a {@link PrimitiveResponse} containing the serialized payload + * string. + * + * @param response the response to encode + * @return a {@link PrimitiveResponse} with encoded payload + */ public static PrimitiveResponse encode(Response response) { StringBuilder sb = new StringBuilder(); sb.append(response.prefix()); @@ -19,6 +30,13 @@ public class ResponseEncoder { response.getSessionId(), response.getRequestId(), sb.toString()); } + /** + * Internal helper to encode any {@link ResponseNode}. + * + * @param node node to encode + * @param sb string builder to append to + * @param depth current indentation depth + */ private static void encodeNode(ResponseNode node, StringBuilder sb, int depth) { if (node instanceof ResponseParameter param) { encodeParameter(param, sb, depth); @@ -27,6 +45,13 @@ public class ResponseEncoder { } } + /** + * Encode a {@link ResponseParameter} into the string builder. + * + * @param param the parameter to encode + * @param sb the output builder + * @param depth indentation depth + */ private static void encodeParameter(ResponseParameter param, StringBuilder sb, int depth) { sb.append(INDENT.repeat(depth)); sb.append(param.key()); @@ -34,6 +59,14 @@ public class ResponseEncoder { sb.append(maskIfNeeded(param.value().toString())); } + /** + * Encode a {@link ResponseBlock}, including its children and terminating with an {@code END} + * marker. + * + * @param block the block to encode + * @param sb the output builder + * @param depth current indentation depth + */ private static void encodeBlock(ResponseBlock block, StringBuilder sb, int depth) { sb.append(INDENT.repeat(depth)); sb.append(block.tag()); @@ -48,6 +81,13 @@ public class ResponseEncoder { sb.append("END"); } + /** + * Quote or escape the provided value if it contains whitespace or single quotes so the encoded + * payload remains parseable. + * + * @param value the raw string value + * @return quoted/escaped value + */ private static String maskIfNeeded(String value) { if (value.contains(" ") || value.contains("'")) { String escaped = value.replace("'", "\\'"); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java index ea22d0a..c3af815 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java @@ -1,3 +1,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +/** + * Marker interface for elements that may appear in a {@link ResponseBody}. + * + *

Implementations include {@link ResponseParameter} and {@link ResponseBlock}. + */ public interface ResponseNode {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java index 4d04293..87f599a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java @@ -1,6 +1,22 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +/** + * A parameter node stored in a {@link ResponseBody}. + * + *

Represents a simple key/value pair. Callers can use {@link #rawValue()} to obtain the string + * representation of the stored value. + * + * @param key the parameter name + * @param value the parameter value + */ public record ResponseParameter(String key, Object value) implements ResponseNode { + /** + * Returns the raw string representation of the stored value. This is a convenience wrapper + * around {@code Object#toString()} and may throw {@link NullPointerException} if the stored + * value is {@code null}. + * + * @return the value as string + */ public String rawValue() { return value.toString(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java index dae5308..e88913f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java @@ -2,11 +2,31 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; +/** + * Abstract {@link Response} specialization indicating a successful outcome. + * + *

Implementations of this class use the {@code +OK} prefix. It provides a protected constructor + * so subclasses can supply the response body content. + */ public abstract class SuccessResponse extends Response { + /** + * Create a successful response with the provided body. + * + * @param sessionId the session id this response targets + * @param requestId the originating request id + * @param body the response body + */ protected SuccessResponse(SessionId sessionId, int requestId, ResponseBody body) { super(sessionId, requestId, body); } + /** + * {@inheritDoc} + * + *

This implementation returns the fixed {@code +OK} prefix. + * + * @return the {@code +OK} prefix + */ @Override public final String prefix() { return "+OK"; From 9766fe52c5e429042a27d1979843af3a25ed6e03 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 14:34:59 +0100 Subject: [PATCH 039/104] Add: OkResponse class as default for successful response with no body --- .../server/network/response/OkResponse.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java new file mode 100644 index 0000000..a3f26c5 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java @@ -0,0 +1,20 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.response; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +/** + * A simple success response with an empty body. + * + *

Use this to acknowledge successful requests that do not carry additional payload data. + */ +public class OkResponse extends SuccessResponse { + /** + * Create a minimal successful response (no body content). + * + * @param sessionId the target session id + * @param requestId the originating request id + */ + public OkResponse(SessionId sessionId, int requestId) { + super(sessionId, requestId, ResponseBody.builder().build()); + } +} From 89753a74791409007e4a80da9e3ca3a8b5263fee Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 17:58:21 +0100 Subject: [PATCH 040/104] Add: RequestContext record --- .../cs108/casono/server/network/parser/RequestContext.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java new file mode 100644 index 0000000..685407f --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java @@ -0,0 +1,5 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + +public record RequestContext(SessionId sessionId, int requestId) {} From db22f12ed581e5eae3294f08eb7883407e4eff2a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:00:09 +0100 Subject: [PATCH 041/104] Add: RequestContext field to abstract Request class BREAKING CHANGE: Request is now an abstract class instead of an interface --- .../casono/server/network/parser/Request.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java index 4018a31..8b3d70f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java @@ -1,4 +1,24 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; + /** Request, produced by the CommandParser */ -public interface Request {} +public abstract class Request { + protected final RequestContext context; + + public Request(RequestContext context) { + this.context = context; + } + + public RequestContext getContext() { + return context; + } + + public SessionId getSessionId() { + return context.sessionId(); + } + + public int getRequestId() { + return context.requestId(); + } +} From f4476ae1e8aec2b6fc6bd22e852760a270a3a035 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:03:26 +0100 Subject: [PATCH 042/104] Add: RawRequest record to contain command and parameters --- .../dbis/cs108/casono/server/network/parser/RawRequest.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java new file mode 100644 index 0000000..fbbc0e5 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java @@ -0,0 +1,5 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +import java.util.List; + +public record RawRequest(String command, List parameters) {} From 34ad8030733a61737b3b21d4eaafb7a677d2aa8a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:07:20 +0100 Subject: [PATCH 043/104] Refactor: ProtocolParser to accept payload string and return RawRequest Prior it took the RawPacket as an argument and returned an PrimitiveRequest --- .../cs108/casono/server/network/parser/ProtocolParser.java | 7 +++---- .../casono/server/network/sessions/SessionReader.java | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java index acb48a0..8f8b4d4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java @@ -1,6 +1,5 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; -import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenClassifier; @@ -19,15 +18,15 @@ public class ProtocolParser { * @param packet the RawPacket containing the recieved data * @return created PrimitiveRequest */ - public static PrimitiveRequest parse(RawPacket packet) { - List rawTokens = Tokenizer.tokenize(packet.payload()); + public static RawRequest parse(String payload) { + List rawTokens = Tokenizer.tokenize(payload); List tokens = TokenClassifier.classify(rawTokens); Iterator iterator = tokens.iterator(); String command = readCommand(iterator); List parameters = readParameters(iterator); - return new PrimitiveRequest(packet.requestId(), command, parameters); + return new RawRequest(command, parameters); } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 7c2a6c7..c9aa4aa 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -2,9 +2,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; @@ -36,8 +36,8 @@ public class SessionReader implements Runnable { rawPacket = transport.read(); logger.debug("Recieved: {}", rawPacket); - PrimitiveRequest primitiveRequest = ProtocolParser.parse(rawPacket); - logger.debug("Parsed request to {}", primitiveRequest); + RawRequest rawRequest = ProtocolParser.parse(rawPacket.payload()); + logger.debug("Parsed request to {}", rawRequest); } catch (EOFException e) { logger.info("Client disconnected"); eventBus.publish(new DisconnectEvent(session.getId())); From cdd5de620bd8fd1500bc39562041f25ffc5009a5 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:10:15 +0100 Subject: [PATCH 044/104] Add: Create PrimitiveRequest from RawRequest with RequestContext --- .../casono/server/network/sessions/SessionReader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index c9aa4aa..0abe830 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -2,9 +2,11 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RawRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestContext; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; @@ -38,6 +40,12 @@ public class SessionReader implements Runnable { RawRequest rawRequest = ProtocolParser.parse(rawPacket.payload()); logger.debug("Parsed request to {}", rawRequest); + + RequestContext requestContext = + new RequestContext(session.getId(), rawPacket.requestId()); + PrimitiveRequest primitiveRequest = + new PrimitiveRequest( + requestContext, rawRequest.command(), rawRequest.parameters()); } catch (EOFException e) { logger.info("Client disconnected"); eventBus.publish(new DisconnectEvent(session.getId())); From edc1b29884bca41bdf2250c3d28914180481dcaf Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:11:37 +0100 Subject: [PATCH 045/104] Add: PrimitiveRequest takes now RequestContext instead of requestId --- .../cs108/casono/server/network/parser/PrimitiveRequest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java index 4ac06de..4135e47 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java @@ -3,4 +3,5 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; import java.util.List; /** Created by the ProtocolParser to allow easy access to the request contents */ -public record PrimitiveRequest(int requestId, String command, List parameters) {} +public record PrimitiveRequest( + RequestContext context, String command, List parameters) {} From d1510ddf8ea2d4288a4d0fbe6d2e437f8633886c Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Tue, 24 Mar 2026 18:12:02 +0100 Subject: [PATCH 046/104] Docs: Write JavaDoc for RequestContext --- .../casono/server/network/parser/RequestContext.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java index 685407f..6881885 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java @@ -2,4 +2,13 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; +/** + * Immutable context for a network request. + * + *

Contains the originating session's identifier and the request's id. Later used to create + * response. + * + * @param sessionId the identifier of the session that initiated the request + * @param requestId the request's numeric id within the session + */ public record RequestContext(SessionId sessionId, int requestId) {} From b0d7dc8b3047d9efb5abdc6f8a73f46f71f3e287 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Wed, 25 Mar 2026 13:47:54 +0100 Subject: [PATCH 047/104] Add: CommandParserDispatcher as field to SessionManager --- .../cs108/casono/server/network/sessions/SessionManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 2ff6e38..c582a67 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; import java.util.Map; @@ -14,12 +15,14 @@ public class SessionManager { private Map sessions; private final EventBus eventBus; private final Logger logger; + private final CommandParserDispatcher dispatcher; /** Constructs a new SessionManager. */ - public SessionManager(EventBus eventBus) { + public SessionManager(EventBus eventBus, CommandParserDispatcher dispatcher) { this.sessions = new ConcurrentHashMap<>(); this.eventBus = eventBus; this.logger = LogManager.getLogger(SessionManager.class); + this.dispatcher = dispatcher; } /** From 6f1b6361bc1ff7fece103573e33cdd3d969e97ee Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Wed, 25 Mar 2026 13:48:30 +0100 Subject: [PATCH 048/104] Add: Create CommandParserDispatcher on startup and pass to SessionManager --- .../ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 126b341..9327139 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -5,6 +5,7 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import java.time.Duration; import java.util.concurrent.Executors; @@ -26,7 +27,8 @@ public class ServerApp { logger.info("Starting server at port {}", port); EventBus eventBus = new EventBus(); - SessionManager sessionManager = new SessionManager(eventBus); + CommandParserDispatcher dispatcher = new CommandParserDispatcher(); + SessionManager sessionManager = new SessionManager(eventBus, dispatcher); eventBus.subscribe(DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); NetworkManager networkManager = new NetworkManager(port, sessionManager); From 92e4fcb2697fcf8fa9564cf19f8a87db8a7c8968 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Wed, 25 Mar 2026 13:50:35 +0100 Subject: [PATCH 049/104] Add: CommandParserDispatcher field to Session and SessionReader --- .../casono/server/network/sessions/Session.java | 15 ++++++++++++++- .../server/network/sessions/SessionReader.java | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 0a9be66..6959ed7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; @@ -12,6 +13,7 @@ public class Session { private final SessionId id; private final TransportLayer transport; private final BlockingQueue responseQueue; + private final CommandParserDispatcher dispatcher; private static final int RESPOND_QUEUE_SIZE = 32; /** @@ -21,9 +23,11 @@ public class Session { * @param eventBus the event bus for publishing events * @throws IOException if an I/O error occurs during initialization */ - public Session(TransportLayer transport, EventBus eventBus) { + public Session( + TransportLayer transport, EventBus eventBus, CommandParserDispatcher dispatcher) { this.id = new SessionId(); this.transport = transport; + this.dispatcher = dispatcher; this.responseQueue = new ArrayBlockingQueue<>(RESPOND_QUEUE_SIZE); } @@ -53,4 +57,13 @@ public class Session { public BlockingQueue getResponseQueue() { return responseQueue; } + + /** + * Returns the CommandParserDispatcher of this session + * + * @return the dispatcher to dispatch PrimitiveRequests to for parsing + */ + public CommandParserDispatcher getDispatcher() { + return dispatcher; + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 0abe830..0b21190 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -2,10 +2,12 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RawRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestContext; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; @@ -19,12 +21,14 @@ public class SessionReader implements Runnable { private final Session session; private final TransportLayer transport; private final EventBus eventBus; + private final CommandParserDispatcher dispatcher; private final Logger logger; public SessionReader(Session session, EventBus eventBus) { this.session = session; this.transport = session.getTransport(); this.eventBus = eventBus; + this.dispatcher = session.getDispatcher(); this.logger = LogManager.getLogger( SessionReader.class.toString() + "-" + session.getId().value()); @@ -46,6 +50,8 @@ public class SessionReader implements Runnable { PrimitiveRequest primitiveRequest = new PrimitiveRequest( requestContext, rawRequest.command(), rawRequest.parameters()); + + Request request = dispatcher.parse(primitiveRequest); } catch (EOFException e) { logger.info("Client disconnected"); eventBus.publish(new DisconnectEvent(session.getId())); From 4430ddb0f33c2d6766c2fe8f2de5169e6c5978c2 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Wed, 25 Mar 2026 13:50:54 +0100 Subject: [PATCH 050/104] Add: Pass CommandParserDispatcher instance to session upon creation --- .../cs108/casono/server/network/sessions/SessionManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index c582a67..bbf1a14 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -34,7 +34,7 @@ public class SessionManager { * @return newly created session */ public Session create(TransportLayer transport) { - Session session = new Session(transport, eventBus); + Session session = new Session(transport, eventBus, dispatcher); SessionReader reader = new SessionReader(session, eventBus); SessionWriter writer = new SessionWriter(session); From 085f97b37eb957636fe97ea80f708921a539d16a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 12:48:16 +0100 Subject: [PATCH 051/104] Rework: Bug report issue templates --- .gitlab/issue_templates/Bug Report.md | 40 ++++++++++++++++++++ .gitlab/issue_templates/bug_report_client.md | 31 --------------- .gitlab/issue_templates/bug_report_server.md | 30 --------------- 3 files changed, 40 insertions(+), 61 deletions(-) create mode 100644 .gitlab/issue_templates/Bug Report.md delete mode 100644 .gitlab/issue_templates/bug_report_client.md delete mode 100644 .gitlab/issue_templates/bug_report_server.md diff --git a/.gitlab/issue_templates/Bug Report.md b/.gitlab/issue_templates/Bug Report.md new file mode 100644 index 0000000..4fcd233 --- /dev/null +++ b/.gitlab/issue_templates/Bug Report.md @@ -0,0 +1,40 @@ +## Bug Report + + +### Environment +- **Branch & Commit:** +- **Operating system:** +- **How was execution started (Gradle task / IDE debug / IDE run):** +- **Java version:** `25` +- **Gradle version**: `9.3.1` + +### Summary + + +### Expected Behavior + + +### Actual Behavior + + +### Steps to Reproduce + + +### Stack Trace / Error Message +``` + +``` + +### Possible Cause / Notes + + +### Checklist +- [ ] I reproduced the problem using the steps above +- [ ] I searched documentation docs for relevant information +- [ ] I added relevant labels + +/label ~bug diff --git a/.gitlab/issue_templates/bug_report_client.md b/.gitlab/issue_templates/bug_report_client.md deleted file mode 100644 index d1b4373..0000000 --- a/.gitlab/issue_templates/bug_report_client.md +++ /dev/null @@ -1,31 +0,0 @@ -## Bug Report - -### Summary - - -### Affected Component - - -### Steps to Reproduce -1. Do this first -2. Then do that next -3. Lastly, see the unexprected error message ... - -### Expected Behavior - - -### Actual Behavior - - -### Stack Trace / Error Message -``` - -``` - -### Possible Cause - - - -/label ~bug - -/label ~client diff --git a/.gitlab/issue_templates/bug_report_server.md b/.gitlab/issue_templates/bug_report_server.md deleted file mode 100644 index 46d7572..0000000 --- a/.gitlab/issue_templates/bug_report_server.md +++ /dev/null @@ -1,30 +0,0 @@ -## Bug Report - -### Summary - - -### Affected Component - - -### Steps to Reproduce -1. Do this first -2. Then do that next -3. Lastly, see the unexprected error message ... - -### Expected Behavior - - -### Actual Behavior - - -### Stack Trace / Error Message -``` - -``` - -### Possible Cause - - -/label ~bug - -/label ~server From c19e3f322957dab8d8317db79565c71d1e410777 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 12:52:59 +0100 Subject: [PATCH 052/104] Rework: Feature request issue templates --- .gitlab/issue_templates/Feature Request.md | 18 +++++++++++++ .../issue_templates/feature_request_client.md | 27 ------------------- .../issue_templates/feature_request_server.md | 27 ------------------- 3 files changed, 18 insertions(+), 54 deletions(-) create mode 100644 .gitlab/issue_templates/Feature Request.md delete mode 100644 .gitlab/issue_templates/feature_request_client.md delete mode 100644 .gitlab/issue_templates/feature_request_server.md diff --git a/.gitlab/issue_templates/Feature Request.md b/.gitlab/issue_templates/Feature Request.md new file mode 100644 index 0000000..5a11cf5 --- /dev/null +++ b/.gitlab/issue_templates/Feature Request.md @@ -0,0 +1,18 @@ +## Feature Request + + +### Summary + + +### Required workarround + + +### Description + + +### Checklist +- [ ] I reproduced the problem using the steps above +- [ ] I searched documentation docs for relevant information +- [ ] I added relevant labels + +/label ~enhancement diff --git a/.gitlab/issue_templates/feature_request_client.md b/.gitlab/issue_templates/feature_request_client.md deleted file mode 100644 index c654230..0000000 --- a/.gitlab/issue_templates/feature_request_client.md +++ /dev/null @@ -1,27 +0,0 @@ -## Feature Request - -### Summary - - -### Motivation / Problem - - -### Description - - -### Affected Components - - - -### Acceptance Criteria - -- [ ] -- [ ] -- [ ] - -### Open Questions / Trade-offs - - -/label ~enhancement - -/label ~client diff --git a/.gitlab/issue_templates/feature_request_server.md b/.gitlab/issue_templates/feature_request_server.md deleted file mode 100644 index 38d3377..0000000 --- a/.gitlab/issue_templates/feature_request_server.md +++ /dev/null @@ -1,27 +0,0 @@ -## Feature Request - -### Summary - - -### Motivation / Problem - - -### Description - - -### Affected Components - - - -### Acceptance Criteria - -- [ ] -- [ ] -- [ ] - -### Open Questions / Trade-offs - - -/label ~enhancement - -/label ~server From a772f2ce0174aa4fad8aefdea995ffc0937b86ab Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 12:53:52 +0100 Subject: [PATCH 053/104] Remove: Protocol change issue template as it is now incorporated into the others --- .gitlab/issue_templates/protocol_change.md | 37 ---------------------- 1 file changed, 37 deletions(-) delete mode 100644 .gitlab/issue_templates/protocol_change.md diff --git a/.gitlab/issue_templates/protocol_change.md b/.gitlab/issue_templates/protocol_change.md deleted file mode 100644 index 6c5d5b2..0000000 --- a/.gitlab/issue_templates/protocol_change.md +++ /dev/null @@ -1,37 +0,0 @@ -## Protocol / API Change - -### Summary - - -### Affected Commands / Responses - - -| Command | Response | Type of Change | Description | -|---------|----------|----------------|-------------| -| | | New / Changed / Removed | | - -### New / Changed Syntax -``` - - -``` - -### Affected Implementation Layers - -- [ ] `Session` -- [ ] `User` or `UserRegistry` -- [ ] `Tokenizer` / `RequestTokenClassifier` -- [ ] `ProtocolParser` -- [ ] `CommandParserDispatcher` + corresponding `CommandParser` -- [ ] `CommandHandler` -- [ ] `Response` hierarchy -- [ ] `GameEngine` or `GameState` -- [ ] Client-side (create your own issue and create link) - -### Motivation - - -/label ~protocol From 72ef67c47d01a2c7c28f672081d4db349d555944 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 12:56:54 +0100 Subject: [PATCH 054/104] Rework: Task issue template --- .gitlab/issue_templates/Task.md | 25 +++++++++++++++++++++++++ .gitlab/issue_templates/task_client.md | 25 ------------------------- .gitlab/issue_templates/task_server.md | 25 ------------------------- 3 files changed, 25 insertions(+), 50 deletions(-) create mode 100644 .gitlab/issue_templates/Task.md delete mode 100644 .gitlab/issue_templates/task_client.md delete mode 100644 .gitlab/issue_templates/task_server.md diff --git a/.gitlab/issue_templates/Task.md b/.gitlab/issue_templates/Task.md new file mode 100644 index 0000000..9455ce6 --- /dev/null +++ b/.gitlab/issue_templates/Task.md @@ -0,0 +1,25 @@ +## Task + + +### Summary + + +### Context + + + +### Current Progress +- [ ] +- [ ] +- [ ] + +### Notes + + +### Checklist +- [ ] I reproduced the problem using the steps above +- [ ] I searched documentation docs for relevant information +- [ ] I added relevant labels +- [ ] I linked to other issues or branches that must be completed first + +/label ~task diff --git a/.gitlab/issue_templates/task_client.md b/.gitlab/issue_templates/task_client.md deleted file mode 100644 index f75a1c4..0000000 --- a/.gitlab/issue_templates/task_client.md +++ /dev/null @@ -1,25 +0,0 @@ -## Task - -### Summary - - -### Context - - -### Affected Components - - -### Definition of Done -- [ ] -- [ ] -- [ ] - -### Notes - - -### Checklist -- [ ] Linked to other issues or branches that must be completed first? - -/label ~task - -/label ~client diff --git a/.gitlab/issue_templates/task_server.md b/.gitlab/issue_templates/task_server.md deleted file mode 100644 index e6206d1..0000000 --- a/.gitlab/issue_templates/task_server.md +++ /dev/null @@ -1,25 +0,0 @@ -## Task - -### Summary - - -### Context - - -### Affected Components - - -### Definition of Done -- [ ] -- [ ] -- [ ] - -### Notes - - -### Checklist -- [ ] Linked to other issues or branches that must be completed first? - -/label ~task - -/label ~server From 62489353550cc5e10d9c9d987c2dd7d6d3d41938 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 13:11:36 +0100 Subject: [PATCH 055/104] Add: Whitespaces after environment description of bug report issue template --- .gitlab/issue_templates/Bug Report.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/issue_templates/Bug Report.md b/.gitlab/issue_templates/Bug Report.md index 4fcd233..2f04712 100644 --- a/.gitlab/issue_templates/Bug Report.md +++ b/.gitlab/issue_templates/Bug Report.md @@ -2,9 +2,9 @@ ### Environment -- **Branch & Commit:** -- **Operating system:** -- **How was execution started (Gradle task / IDE debug / IDE run):** +- **Branch & Commit:** +- **Operating system:** +- **How was execution started (Gradle task / IDE debug / IDE run):** - **Java version:** `25` - **Gradle version**: `9.3.1` From 9da31ac4dce5a83a272c5535e40d6a4c0749882e Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 13:12:51 +0100 Subject: [PATCH 056/104] Remove: Unnecessary checklist item introduced by copy & pasting from bug report issue template --- .gitlab/issue_templates/Task.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab/issue_templates/Task.md b/.gitlab/issue_templates/Task.md index 9455ce6..27761d5 100644 --- a/.gitlab/issue_templates/Task.md +++ b/.gitlab/issue_templates/Task.md @@ -17,8 +17,7 @@ ### Checklist -- [ ] I reproduced the problem using the steps above -- [ ] I searched documentation docs for relevant information +- [ ] I outlined checkpoints describing phases of my work related to this task - [ ] I added relevant labels - [ ] I linked to other issues or branches that must be completed first From 68891815ee8260a242fce8d801ae3749b65ab253 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 14:15:42 +0100 Subject: [PATCH 057/104] Docs: Create CONTRIBUTING.md with guidelines and workflows --- CONTRIBUTING.md | 208 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..92a520a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,208 @@ +# Contribution Guidelines +This document describes the conventions and workflows everyone must follow to keep the codebase consistent and the collaboration smooth. +If you notice a violation, speak to the person involved respectfully. + +Since this project is part of a course at the University of Basel, the [Code of Conduct](https://www.unibas.ch/de/Universitaet/Administration-Services/Vizerektorat-People-And-Culture/Persoenliche-Integritaet/Code-of-Conduct.html) applies. + + +## Table of Contents +- [Contribution Guidelines](#contribution-guidelines) + - [Table of Contents](#table-of-contents) + - [Issues \& Tasks](#issues--tasks) + - [Creating an issue](#creating-an-issue) + - [During implementation](#during-implementation) + - [Collaborative work](#collaborative-work) + - [Git Workflow](#git-workflow) + - [Creating a branch](#creating-a-branch) + - [Working on a branch](#working-on-a-branch) + - [Commit Messages](#commit-messages) + - [Rules](#rules) + - [Examples](#examples) + - [Code Style](#code-style) + - [Linter](#linter) + - [Formatter](#formatter) + - [General guidelines](#general-guidelines) + - [CI/CD Pipeline](#cicd-pipeline) + - [Before pushing](#before-pushing) + - [Merge Requests](#merge-requests) + - [Opening a MR](#opening-a-mr) + - [Merging](#merging) + - [After merging](#after-merging) + - [Be human](#be-human) + + +## Issues & Tasks +Every piece of work - whether a new feature, a bug fix, or a refactoring - must be tracked as an +Issue or Task in GitLab **before** any implementation begins. + +### Creating an issue +1. Open a new Issue or Task using the **relevant template** provided in the repository. +2. Fill in **all fields** specified by the template thoughtfully and completely. A well-written issue is the single source of truth for the work being done - treat it accordingly. +3. Work through the **checklist** in the template before marking the issue as ready. Do not skip items. + +### During implementation +- If you encounter a problem or an unexpected finding while working on an issue, record it as a **comment** on the issue. This keeps the history intact and visible to the whole team. +- **Do not restructurally edit the original description** to incorporate new information. The description reflects the intent at the time the issue was created; comments document what happened along the way. + +### Collaborative work +- When multiple people are working on the same issue, **prefer issue comments over private messages** for coordination. This keeps the current status, decisions, and open questions + centrally visible and searchable. +- Before starting work that overlaps with an existing issue, check its comment thread first to avoid duplicating effort. + + +## Git Workflow +We use a **feature branch -> main** strategy. The `main` branch is always in a releasable state. + +### Creating a branch +We follow the [**Conventional Branch**](https://conventional-branch.github.io/) specification. Branch names follow this pattern: + +``` +/ +``` + +| Type | When to use | +|------------|--------------------------------------------------| +| `feat` | New feature or capability | +| `fix` | Bug fix | +| `refactor` | Restructuring without behaviour change | +| `test` | Adding or fixing tests | +| `ci` | Pipeline, Gradle, or tooling changes | +| `docs` | Documentation only | + +**Examples:** + +``` +feat/reconnect-command +fix/session-writer-flush +refactor/user-registry-cleanup +docs/contributing +``` + +### Working on a branch +Keep branches short-lived. A branch should represent one cohesive unit of work. + +It is permissible to commit changes within a feature branch that cause the program to become non-functional, but these should be fixed as soon as possible. In any case, the code that is merged into `main` must be functional. + +And most importantly: **Do not commit directly to `main`**. + + +## Commit Messages +We follow the [**Conventional Commits**](https://www.conventionalcommits.org/) specification. Every commit message must have the form: + +``` +: + +[optional body] +``` + +### Rules +The summary line must be **<= 72 characters**, written in the **imperative mood** (e.g. "add", not "added" or "adds"). + +### Examples +``` +Reat: Add RECONNECT command handler + +The handler re-associates an existing User with a new Session after +a connection drop, preserving in-flight state. +``` + +``` +Fix: Flush output stream before closing +``` + +``` +Ci: Tighten Checkstyle failure policy to allow_failure: false +``` + +``` +Refactor: Replace ArrayList with CopyOnWriteArrayList +``` + + +## Code Style +Code formatting is enforced automatically. **Do not submit a MR with formatting violations.** + +### Linter +We use **Checkstyle** as our linter with a custom set of rules tailored to our project. + +Checkstyle runs on every pipeline. Fix all violations locally before pushing: + +```bash +./gradlew checkstyleMain checkstyleTest +``` + + +### Formatter +We use **Spotless** with the **[Google](https://google.github.io/styleguide/javaguide.html) / [AOSP Java style](https://source.android.com/docs/core/architecture/hidl/code-style?hl=en)**: + +- **Indentation:** 4 spaces (no tabs) +- **Line length:** 100 characters +- No decorative blank lines directly after opening braces `{` +- Blank lines are reserved for separating logical sections within a block + +Run the formatter before committing: + +```bash +./gradlew spotlessApply +``` + +Check without applying: + +```bash +./gradlew spotlessCheck +``` + +### General guidelines +- Add **JavaDoc** docstrings to classes, interfaces, records and methods. +- Exercise **clean architecture** +- Prefer **stateless components** +- Use **`record` types** for immutable data carriers. +- Log with **Log4J 2** (`log4j-api`). Use the appropriate level (`DEBUG` for pipeline internals, `INFO` for lifecycle events, `WARN`/`ERROR` for recoverable/unrecoverable problems). + + +## CI/CD Pipeline +The pipeline runs automatically on every push. It has four stages: + +``` +lint > report > build > test +``` + +| Stage | Jobs | +|----------|--------------------------------------------| +| `lint` | Spotless check, Checkstyle | +| `report` | Code Quality JSON conversion (only for mr) | +| `build` | `./gradlew assemble` | +| `test` | `./gradlew test` + JUnit result reporting | + +### Before pushing +Run the full check suite locally to avoid a broken pipeline: + +```bash +./gradlew spotlessCheck checkstyleMain checkstyleTest build test +``` + +A red pipeline blocks merging. Fix failures before creating your merge request. + + +## Merge Requests + +### Opening a MR +- Target branch is always **`main`**. +- Fill in the MR description: what changed and why. Link the relevant issue (with 'Closing #x') if one exists. + +### Merging +A MR can be merged when **all main CI pipeline stages are green** (lint, build, test). + +No explicit peer approval is required, but leaving a note or question in the MR thread for non-trivial changes is encouraged. +If you spot a problem in someone else's open MR, comment - **do not push directly to their branch** and try to fix the issue yourself. + +### After merging +Delete the feature branch after the MR is merged. GitLab can do this automatically via the +"Delete source branch" checkbox in the MR. + + +## Be human +We are all human. +We all forget things or make mistakes sometimes. + +It’s important that we look out for one another and **work together as a team**. From 69a5a94028014847f7d135a7a4aa8f839f4005dc Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:09:33 +0100 Subject: [PATCH 058/104] Add: CommandHandler interface for executing requests --- .../casono/server/network/command/CommandHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java new file mode 100644 index 0000000..9c07c56 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.command; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; + +public interface CommandHandler { + void execute(Request request); +} From d9f6838e05e169a516c3157b23c5bacaa6f68f6c Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:20:25 +0100 Subject: [PATCH 059/104] Add: UnknownRequestException class to throw when encountering unknown request type --- .../network/command/UnknownRequestException.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java new file mode 100644 index 0000000..e7889b0 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java @@ -0,0 +1,14 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.command; + +public class UnknownRequestException extends RuntimeException { + private final String requestName; + + public UnknownRequestException(String message, String requestName) { + this.requestName = requestName; + super(message); + } + + public String getRequestName() { + return requestName; + } +} From fd17b49ed9b7f47e8d2043e355a56805a8722365 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:51:32 +0100 Subject: [PATCH 060/104] Add: CommandRouter to route Request to matching CommandHandler --- .../server/network/command/CommandRouter.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java new file mode 100644 index 0000000..186c1fe --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java @@ -0,0 +1,24 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.command; + +import java.util.HashMap; +import java.util.Map; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; + +public class CommandRouter { + private final Map, CommandHandler> handlers = new HashMap<>(); + + public void register(Class request, CommandHandler handler) { + handlers.put(request, handler); + } + + public void execute(Request request) { + CommandHandler handler = handlers.get(request.getClass()); + + if (handler == null) { + String requestName = request.getClass().toString(); + throw new UnknownRequestException("Unable to execute request " + requestName + ". Type unknown", requestName); + } + handler.execute(request); + } +} From 20047405416fa34ad97995399adbf09a71d8efa1 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:53:19 +0100 Subject: [PATCH 061/104] Add: CommandHandler interface to be generic --- .../cs108/casono/server/network/command/CommandHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java index 9c07c56..34228c7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java @@ -2,6 +2,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; -public interface CommandHandler { - void execute(Request request); +public interface CommandHandler { + void execute(T request); } From 52c347d233dcab7222f1b3a0bc3f883b9e9b7ff4 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:55:26 +0100 Subject: [PATCH 062/104] Add: Modify CommandRouter to use generic CommandHandler type --- .../casono/server/network/command/CommandRouter.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java index 186c1fe..282c6c9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java @@ -6,14 +6,16 @@ import java.util.Map; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; public class CommandRouter { - private final Map, CommandHandler> handlers = new HashMap<>(); + private final Map, CommandHandler> handlers = new HashMap<>(); - public void register(Class request, CommandHandler handler) { + public void register(Class request, CommandHandler handler) { handlers.put(request, handler); } + // Safe, because during registration, it's ensured that the provided CommandHandler only receives requests it can handle. + @SuppressWarnings("unchecked") public void execute(Request request) { - CommandHandler handler = handlers.get(request.getClass()); + CommandHandler handler = (CommandHandler) handlers.get(request.getClass()); if (handler == null) { String requestName = request.getClass().toString(); From a520f69f3e9bd277e2a0884b84a7c355d712d39a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:56:22 +0100 Subject: [PATCH 063/104] Fix: Ensure matching type at compile-time --- .../dbis/cs108/casono/server/network/command/CommandRouter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java index 282c6c9..0dafc58 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java @@ -8,7 +8,7 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; public class CommandRouter { private final Map, CommandHandler> handlers = new HashMap<>(); - public void register(Class request, CommandHandler handler) { + public void register(Class request, CommandHandler handler) { handlers.put(request, handler); } From d25f533ee9b13ff86253307e7cbd17bb38270ec7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:57:00 +0100 Subject: [PATCH 064/104] Add: Integrate CommandRouter into SessionManager for request routing --- .../casono/server/network/sessions/SessionManager.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index bbf1a14..a33e7b0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; @@ -16,13 +17,15 @@ public class SessionManager { private final EventBus eventBus; private final Logger logger; private final CommandParserDispatcher dispatcher; + private final CommandRouter router; /** Constructs a new SessionManager. */ - public SessionManager(EventBus eventBus, CommandParserDispatcher dispatcher) { + public SessionManager(EventBus eventBus, CommandParserDispatcher dispatcher, CommandRouter router) { this.sessions = new ConcurrentHashMap<>(); this.eventBus = eventBus; this.logger = LogManager.getLogger(SessionManager.class); this.dispatcher = dispatcher; + this.router = router; } /** @@ -34,7 +37,7 @@ public class SessionManager { * @return newly created session */ public Session create(TransportLayer transport) { - Session session = new Session(transport, eventBus, dispatcher); + Session session = new Session(transport, eventBus, dispatcher, router); SessionReader reader = new SessionReader(session, eventBus); SessionWriter writer = new SessionWriter(session); From 628e86a964a62b2ba9c280857603b3703c691206 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:58:25 +0100 Subject: [PATCH 065/104] Add: Pass CommandRouter to Session and SessionReader --- .../cs108/casono/server/network/sessions/Session.java | 9 ++++++++- .../casono/server/network/sessions/SessionReader.java | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 6959ed7..0c5027b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; @@ -14,6 +15,7 @@ public class Session { private final TransportLayer transport; private final BlockingQueue responseQueue; private final CommandParserDispatcher dispatcher; + private final CommandRouter router; private static final int RESPOND_QUEUE_SIZE = 32; /** @@ -24,10 +26,11 @@ public class Session { * @throws IOException if an I/O error occurs during initialization */ public Session( - TransportLayer transport, EventBus eventBus, CommandParserDispatcher dispatcher) { + TransportLayer transport, EventBus eventBus, CommandParserDispatcher dispatcher, CommandRouter router) { this.id = new SessionId(); this.transport = transport; this.dispatcher = dispatcher; + this.router = router; this.responseQueue = new ArrayBlockingQueue<>(RESPOND_QUEUE_SIZE); } @@ -66,4 +69,8 @@ public class Session { public CommandParserDispatcher getDispatcher() { return dispatcher; } + + public CommandRouter getRouter() { + return router; + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 0b21190..8ba5c62 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; @@ -22,6 +23,7 @@ public class SessionReader implements Runnable { private final TransportLayer transport; private final EventBus eventBus; private final CommandParserDispatcher dispatcher; + private final CommandRouter router; private final Logger logger; public SessionReader(Session session, EventBus eventBus) { @@ -29,6 +31,7 @@ public class SessionReader implements Runnable { this.transport = session.getTransport(); this.eventBus = eventBus; this.dispatcher = session.getDispatcher(); + this.router = session.getRouter(); this.logger = LogManager.getLogger( SessionReader.class.toString() + "-" + session.getId().value()); @@ -50,8 +53,11 @@ public class SessionReader implements Runnable { PrimitiveRequest primitiveRequest = new PrimitiveRequest( requestContext, rawRequest.command(), rawRequest.parameters()); + logger.debug("Converted to {}", primitiveRequest); Request request = dispatcher.parse(primitiveRequest); + + router.execute(request); } catch (EOFException e) { logger.info("Client disconnected"); eventBus.publish(new DisconnectEvent(session.getId())); From 9a6ad9f1bb2b857c083c0cc015494e2daaf41d28 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 17:59:41 +0100 Subject: [PATCH 066/104] Add: Create CommandRouter at server startup and pass to SessionManager --- .../ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 9327139..b9e6679 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -3,6 +3,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.TestCommandHandler; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; @@ -28,7 +30,9 @@ public class ServerApp { EventBus eventBus = new EventBus(); CommandParserDispatcher dispatcher = new CommandParserDispatcher(); - SessionManager sessionManager = new SessionManager(eventBus, dispatcher); + CommandRouter router = new CommandRouter(); + + SessionManager sessionManager = new SessionManager(eventBus, dispatcher, router); eventBus.subscribe(DisconnectEvent.class, event -> sessionManager.onDisconnect(event)); NetworkManager networkManager = new NetworkManager(port, sessionManager); From a9ffb4daeb19dc2f1f60bca63c1b8e27a7759a5a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 18:01:57 +0100 Subject: [PATCH 067/104] Style: Apply formatting by Spotless --- .../dmi/dbis/cs108/casono/server/ServerApp.java | 1 - .../casono/server/network/command/CommandRouter.java | 12 +++++++----- .../casono/server/network/sessions/Session.java | 5 ++++- .../server/network/sessions/SessionManager.java | 3 ++- .../server/network/sessions/SessionReader.java | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index b9e6679..2391450 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -4,7 +4,6 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.TestCommandHandler; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java index 0dafc58..0badeff 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java @@ -1,10 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; import java.util.HashMap; import java.util.Map; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; - public class CommandRouter { private final Map, CommandHandler> handlers = new HashMap<>(); @@ -12,14 +11,17 @@ public class CommandRouter { handlers.put(request, handler); } - // Safe, because during registration, it's ensured that the provided CommandHandler only receives requests it can handle. + // Safe, because during registration, it's ensured that the provided CommandHandler only + // receives requests it can handle. @SuppressWarnings("unchecked") public void execute(Request request) { - CommandHandler handler = (CommandHandler) handlers.get(request.getClass()); + CommandHandler handler = + (CommandHandler) handlers.get(request.getClass()); if (handler == null) { String requestName = request.getClass().toString(); - throw new UnknownRequestException("Unable to execute request " + requestName + ". Type unknown", requestName); + throw new UnknownRequestException( + "Unable to execute request " + requestName + ". Type unknown", requestName); } handler.execute(request); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 0c5027b..d6e2094 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -26,7 +26,10 @@ public class Session { * @throws IOException if an I/O error occurs during initialization */ public Session( - TransportLayer transport, EventBus eventBus, CommandParserDispatcher dispatcher, CommandRouter router) { + TransportLayer transport, + EventBus eventBus, + CommandParserDispatcher dispatcher, + CommandRouter router) { this.id = new SessionId(); this.transport = transport; this.dispatcher = dispatcher; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index a33e7b0..65a97a3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -20,7 +20,8 @@ public class SessionManager { private final CommandRouter router; /** Constructs a new SessionManager. */ - public SessionManager(EventBus eventBus, CommandParserDispatcher dispatcher, CommandRouter router) { + public SessionManager( + EventBus eventBus, CommandParserDispatcher dispatcher, CommandRouter router) { this.sessions = new ConcurrentHashMap<>(); this.eventBus = eventBus; this.logger = LogManager.getLogger(SessionManager.class); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 8ba5c62..cd74de9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -56,7 +56,7 @@ public class SessionReader implements Runnable { logger.debug("Converted to {}", primitiveRequest); Request request = dispatcher.parse(primitiveRequest); - + router.execute(request); } catch (EOFException e) { logger.info("Client disconnected"); From 8ed1bab0671e3101025d46d4d10153ca770c1aee Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 18:09:07 +0100 Subject: [PATCH 068/104] Style: Put call to superclass constructor before variable assignment in UnknownRequestException constructor --- .../casono/server/network/command/UnknownRequestException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java index e7889b0..60c7fa3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java @@ -4,8 +4,8 @@ public class UnknownRequestException extends RuntimeException { private final String requestName; public UnknownRequestException(String message, String requestName) { - this.requestName = requestName; super(message); + this.requestName = requestName; } public String getRequestName() { From 58d06fad39f68de12c6034ac1c7b8388ef52219c Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Thu, 26 Mar 2026 18:10:32 +0100 Subject: [PATCH 069/104] Style: Line length in SessionManager --- .../server/network/sessions/SessionManager.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 65a97a3..b3d52a6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -42,12 +42,14 @@ public class SessionManager { SessionReader reader = new SessionReader(session, eventBus); SessionWriter writer = new SessionWriter(session); - Thread readerThread = Thread.ofVirtual() - .name("session-" + session.getId().value() + "-reader") - .unstarted(reader); - Thread writerThread = Thread.ofVirtual() - .name("session-" + session.getId().value() + "-writer") - .unstarted(writer); + Thread readerThread = + Thread.ofVirtual() + .name("session-" + session.getId().value() + "-reader") + .unstarted(reader); + Thread writerThread = + Thread.ofVirtual() + .name("session-" + session.getId().value() + "-writer") + .unstarted(writer); sessions.put(session.getId(), new SessionHandle(session, readerThread, writerThread)); readerThread.start(); From 8313a3b7770bc91513685744f6d852dc383e0fc4 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 28 Mar 2026 13:01:13 +0100 Subject: [PATCH 070/104] Add: lastActivity field to Session and update from SessionReader --- .../cs108/casono/server/network/sessions/Session.java | 11 +++++++++++ .../casono/server/network/sessions/SessionReader.java | 1 + 2 files changed, 12 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index d6e2094..4cdda34 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -6,12 +6,14 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispat import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; +import java.time.Instant; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** Represents a client session in the network server. */ public class Session { private final SessionId id; + private Instant lastActivity; private final TransportLayer transport; private final BlockingQueue responseQueue; private final CommandParserDispatcher dispatcher; @@ -31,6 +33,7 @@ public class Session { CommandParserDispatcher dispatcher, CommandRouter router) { this.id = new SessionId(); + this.lastActivity = Instant.now(); this.transport = transport; this.dispatcher = dispatcher; this.router = router; @@ -46,6 +49,14 @@ public class Session { return this.id; } + public Instant getLastInboundActivity() { + return lastActivity; + } + + public void updateLastInboundActivity() { + this.lastActivity = Instant.now(); + } + /** * Returns the TransportLayer of this session * diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index cd74de9..ad90468 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -43,6 +43,7 @@ public class SessionReader implements Runnable { RawPacket rawPacket = null; try { rawPacket = transport.read(); + session.updateLastInboundActivity(); logger.debug("Recieved: {}", rawPacket); RawRequest rawRequest = ProtocolParser.parse(rawPacket.payload()); From c1cf6c1f83599600086baf992ca2cd50bbc6b8df Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 28 Mar 2026 13:01:43 +0100 Subject: [PATCH 071/104] Add: getAllSessions method to SessionManager --- .../casono/server/network/sessions/SessionManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index b3d52a6..8dae02d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -6,8 +6,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; +import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -109,4 +111,8 @@ public class SessionManager { return handle.session(); } + + public Collection getAllSessions() { + return sessions.values().stream().map(SessionHandle::session).collect(Collectors.toList()); + } } From 1547eda410fa84e79e1b8199342e7239689b0354 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 28 Mar 2026 13:11:59 +0100 Subject: [PATCH 072/104] Add: SessionDisconnectJob to publish DisconnectEvent when client timeouts --- .../sessions/SessionDisconnectJob.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionDisconnectJob.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionDisconnectJob.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionDisconnectJob.java new file mode 100644 index 0000000..6fd481d --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionDisconnectJob.java @@ -0,0 +1,40 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; +import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; +import java.time.Duration; +import java.time.Instant; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class SessionDisconnectJob implements Runnable { + private final Logger logger; + private final SessionManager sessionManager; + private final EventBus eventBus; + private final Duration timeoutThreshold; + + public SessionDisconnectJob( + SessionManager sessionManager, EventBus eventBus, Duration timeoutThreshold) { + this.logger = LogManager.getLogger(SessionDisconnectJob.class); + this.sessionManager = sessionManager; + this.eventBus = eventBus; + this.timeoutThreshold = timeoutThreshold; + } + + @Override + public void run() { + logger.debug("Job started."); + Instant threshold = Instant.now().minus(timeoutThreshold); + + for (Session session : sessionManager.getAllSessions()) { + if (session.getLastInboundActivity().isBefore(threshold)) { + eventBus.publish(new DisconnectEvent(session.getId())); + logger.info( + "Initiated disconnect of {}, as it hasn't been active since a while", + session.getId()); + } + } + + logger.debug("Job finished."); + } +} From fc4a88ee95afc1443cf3ab2a671ce0bead497987 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 28 Mar 2026 13:12:30 +0100 Subject: [PATCH 073/104] Add: SessionDisconnectJob scheduling to ServerApp --- .../dbis/cs108/casono/server/ServerApp.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 2391450..e76e877 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -7,6 +7,7 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; +import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionDisconnectJob; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import java.time.Duration; import java.util.concurrent.Executors; @@ -17,9 +18,12 @@ import org.apache.logging.log4j.Logger; /** Application class for starting the server. */ public class ServerApp { - public static final int USER_CLEANUP_JOB_DELAY = 0; - public static final int USER_CLEANUP_JOB_PERIOD = 10; - public static final int USER_CLEANUP_JOB_RECONNECT_THRESHOLD = 10; + private static final int USER_CLEANUP_JOB_DELAY = 0; + private static final int USER_CLEANUP_JOB_PERIOD = 10; + private static final int USER_CLEANUP_JOB_RECONNECT_THRESHOLD = 10; + private static final int SESSION_DISCONNECT_JOB_DELAY = 0; + private static final int SESSION_DISCONNECT_JOB_PERIOD = 2; + private static final int SESSION_DISCONNECT_JOB_TIMEOUT = 5; public static void start(String arg) { int port = Integer.parseInt(arg); @@ -45,6 +49,14 @@ public class ServerApp { USER_CLEANUP_JOB_DELAY, USER_CLEANUP_JOB_PERIOD, TimeUnit.SECONDS); + scheduler.scheduleAtFixedRate( + new SessionDisconnectJob( + sessionManager, + eventBus, + Duration.ofSeconds(SESSION_DISCONNECT_JOB_TIMEOUT)), + SESSION_DISCONNECT_JOB_DELAY, + SESSION_DISCONNECT_JOB_PERIOD, + TimeUnit.SECONDS); networkManager.start(); } From 1f4ccb10333b6cf77987e105104bfb64dc6afcf9 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sat, 28 Mar 2026 13:12:43 +0100 Subject: [PATCH 074/104] Docs: JavaDoc for Session --- .../dbis/cs108/casono/server/network/sessions/Session.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 4cdda34..3fc97e5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -49,10 +49,16 @@ public class Session { return this.id; } + /** + * Gets the timestamp of the last inbound activity for this session. + * + * @return an {@link Instant} representing the time of the last inbound activity + */ public Instant getLastInboundActivity() { return lastActivity; } + /** Updates the timestamp of the last inbound activity for this session. */ public void updateLastInboundActivity() { this.lastActivity = Instant.now(); } From db9ea45530a2c2c81fe53660fc8ee31ed74705b0 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 12:06:52 +0200 Subject: [PATCH 075/104] Add: Exception to throw when required Parameter is not found --- .../network/parser/MissingParameterException.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java new file mode 100644 index 0000000..85080ef --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java @@ -0,0 +1,14 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +public class MissingParameterException extends RuntimeException { + private final String parameterKey; + + public MissingParameterException(String message, String parameterKey) { + super(message); + this.parameterKey = parameterKey; + } + + public String getParameterKey() { + return parameterKey; + } +} From ed914941297f8b0a6c692bddadb23cc51f4705da Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 12:38:44 +0200 Subject: [PATCH 076/104] Add: Exception to throw when error during parsing occurs --- .../server/network/parser/ParameterParseException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java new file mode 100644 index 0000000..e4e31e7 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +public class ParameterParseException extends RuntimeException { + public ParameterParseException(String message, Throwable cause) { + super(message, cause); + } +} From 160ec55957d4aaf9c0dabd52f9ec35d07adc59d9 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 12:39:37 +0200 Subject: [PATCH 077/104] Add: ThrowingParser interface used to implicitly convert --- .../cs108/casono/server/network/parser/ThrowingParser.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java new file mode 100644 index 0000000..52f76b0 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java @@ -0,0 +1,6 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +@FunctionalInterface +interface ThrowingParser { + T parse(String value) throws Exception; +} \ No newline at end of file From 2feb0579e2b054ee1da30a0ebf5c3617463f4754 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 12:40:59 +0200 Subject: [PATCH 078/104] Add: RequestParameterAccessor as utility class for simplified access of parameters of PrimitiveRequest --- .../parser/RequestParameterAccessor.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java new file mode 100644 index 0000000..ce5ddd8 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -0,0 +1,59 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class RequestParameterAccessor { + private final Map index; + + public RequestParameterAccessor(List parameters) { + this.index = parameters.stream() + .collect(Collectors.toUnmodifiableMap( + Parameter::key, + Parameter::value + )); + } + + public String require(String key) throws MissingParameterException { + String value = index.get(key); + if (value == null) { + throw new MissingParameterException("Required parameter with key '" + key + "' is missing.", key); + } + return value; + } + + public T require(String key, ThrowingParser parser) throws MissingParameterException, ParameterParseException { + String value = require(key); + try { + return parser.parse(value); + } catch (Exception e) { + throw new ParameterParseException("Error while parsing with specified parser", e); + } + } + + public String optional(String key, String defaultValue) { + String value = index.get(key); + if (value == null) { + return defaultValue; + } + return value; + } + + public T optional(String key, T defaultValue, ThrowingParser parser) throws ParameterParseException { + String value = index.get(key); + if (value == null) { + return defaultValue; + } + + try { + return parser.parse(value); + } catch (Exception e) { + throw new ParameterParseException("Error while parsing with specified parser", e); + } + } + + public boolean containsKey(String key) { + return index.containsKey(key); + } +} From e6b62726bd52d65dff7a9f2862d1f22eb32336ec Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 12:56:15 +0200 Subject: [PATCH 079/104] Docs: Add JavaDoc to all new interfaces, classes and methods Co-authored-by: Copilot --- .../parser/MissingParameterException.java | 12 +++++ .../parser/ParameterParseException.java | 7 +++ .../parser/RequestParameterAccessor.java | 51 +++++++++++++++++++ .../server/network/parser/ThrowingParser.java | 14 ++++- 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java index 85080ef..55e32fa 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java @@ -1,13 +1,25 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +/** Exception thrown when a required parameter key is not found. */ public class MissingParameterException extends RuntimeException { private final String parameterKey; + /** + * Creates a new exception for a missing required parameter. + * + * @param message human-readable description of the missing parameter + * @param parameterKey key of the parameter that could not be found + */ public MissingParameterException(String message, String parameterKey) { super(message); this.parameterKey = parameterKey; } + /** + * Returns the missing parameter key. + * + * @return key of the parameter that could not be found + */ public String getParameterKey() { return parameterKey; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java index e4e31e7..af727bd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java @@ -1,6 +1,13 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +/** Exception thrown when a parameter value cannot be converted to the requested type. */ public class ParameterParseException extends RuntimeException { + /** + * Creates a new parse exception with a root cause. + * + * @param message human-readable description of the parsing failure + * @param cause original exception thrown during parsing + */ public ParameterParseException(String message, Throwable cause) { super(message, cause); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java index ce5ddd8..cb1998d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -4,9 +4,20 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +/** + * Provides typed access to a request's parameters by indexing them by key. + * + *

Supports required and optional lookups, with optional conversion from {@link String} values to + * domain-specific types via parser functions. + */ public class RequestParameterAccessor { private final Map index; + /** + * Creates an accessor + * + * @param parameters to use + */ public RequestParameterAccessor(List parameters) { this.index = parameters.stream() .collect(Collectors.toUnmodifiableMap( @@ -15,6 +26,13 @@ public class RequestParameterAccessor { )); } + /** + * Returns the raw value for a required parameter key. + * + * @param key parameter key to look up + * @return raw parameter value + * @throws MissingParameterException if no parameter with the given key exists + */ public String require(String key) throws MissingParameterException { String value = index.get(key); if (value == null) { @@ -23,6 +41,16 @@ public class RequestParameterAccessor { return value; } + /** + * Returns a parsed value for a required parameter key. + * + * @param key parameter key to look up + * @param parser parser used to convert the raw value + * @param target type returned by the parser + * @return parsed parameter value + * @throws MissingParameterException if no parameter with the given key exists + * @throws ParameterParseException if parsing the raw value fails + */ public T require(String key, ThrowingParser parser) throws MissingParameterException, ParameterParseException { String value = require(key); try { @@ -32,6 +60,13 @@ public class RequestParameterAccessor { } } + /** + * Returns the raw value for a parameter key or the provided default value if missing. + * + * @param key parameter key to look up + * @param defaultValue value returned when the key does not exist + * @return found parameter value or {@code defaultValue} if absent + */ public String optional(String key, String defaultValue) { String value = index.get(key); if (value == null) { @@ -40,6 +75,16 @@ public class RequestParameterAccessor { return value; } + /** + * Returns a parsed value for a parameter key or the provided default value if missing. + * + * @param key parameter key to look up + * @param defaultValue value returned when the key does not exist + * @param parser parser used to convert the raw value + * @param target type returned by the parser + * @return parsed parameter value or {@code defaultValue} if absent + * @throws ParameterParseException if parsing the raw value fails + */ public T optional(String key, T defaultValue, ThrowingParser parser) throws ParameterParseException { String value = index.get(key); if (value == null) { @@ -53,6 +98,12 @@ public class RequestParameterAccessor { } } + /** + * Checks whether a parameter with the given key exists. + * + * @param key parameter key to check + * @return {@code true} if the key exists, otherwise {@code false} + */ public boolean containsKey(String key) { return index.containsKey(key); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java index 52f76b0..af1ec9b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java @@ -1,6 +1,18 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +/** + * Functional parser interface used to convert a raw string parameter into a target type. + * + * @param target type produced by the parser + */ @FunctionalInterface interface ThrowingParser { + /** + * Parses the provided raw parameter value. + * + * @param value raw parameter value + * @return parsed value + * @throws Exception if the value cannot be parsed + */ T parse(String value) throws Exception; -} \ No newline at end of file +} From d990e37a686868ec9ba91a0289a1ece308c45054 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 13:01:42 +0200 Subject: [PATCH 080/104] Add: parameterKey field to ParameterParseException (docstrings included) --- .../network/parser/ParameterParseException.java | 15 ++++++++++++++- .../network/parser/RequestParameterAccessor.java | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java index af727bd..97628a6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java @@ -2,13 +2,26 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; /** Exception thrown when a parameter value cannot be converted to the requested type. */ public class ParameterParseException extends RuntimeException { + private final String parameterKey; + /** * Creates a new parse exception with a root cause. * * @param message human-readable description of the parsing failure + * @param parameterKey key for whose value the error occured * @param cause original exception thrown during parsing */ - public ParameterParseException(String message, Throwable cause) { + public ParameterParseException(String message, String parameterKey, Throwable cause) { super(message, cause); + this.parameterKey = parameterKey; + } + + /** + * Returns the missing parameter key. + * + * @return key for whose value the error occured + */ + public String getParameterKey() { + return parameterKey; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java index cb1998d..79ceac6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -56,7 +56,7 @@ public class RequestParameterAccessor { try { return parser.parse(value); } catch (Exception e) { - throw new ParameterParseException("Error while parsing with specified parser", e); + throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); } } @@ -94,7 +94,7 @@ public class RequestParameterAccessor { try { return parser.parse(value); } catch (Exception e) { - throw new ParameterParseException("Error while parsing with specified parser", e); + throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); } } From 9390c3503ae8cdfaf2591101a22e4dbefc93cb1e Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 13:02:16 +0200 Subject: [PATCH 081/104] Style: Formatting by Spotless --- .../parser/RequestParameterAccessor.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java index 79ceac6..a79f7b1 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -19,11 +19,9 @@ public class RequestParameterAccessor { * @param parameters to use */ public RequestParameterAccessor(List parameters) { - this.index = parameters.stream() - .collect(Collectors.toUnmodifiableMap( - Parameter::key, - Parameter::value - )); + this.index = + parameters.stream() + .collect(Collectors.toUnmodifiableMap(Parameter::key, Parameter::value)); } /** @@ -36,7 +34,8 @@ public class RequestParameterAccessor { public String require(String key) throws MissingParameterException { String value = index.get(key); if (value == null) { - throw new MissingParameterException("Required parameter with key '" + key + "' is missing.", key); + throw new MissingParameterException( + "Required parameter with key '" + key + "' is missing.", key); } return value; } @@ -51,7 +50,8 @@ public class RequestParameterAccessor { * @throws MissingParameterException if no parameter with the given key exists * @throws ParameterParseException if parsing the raw value fails */ - public T require(String key, ThrowingParser parser) throws MissingParameterException, ParameterParseException { + public T require(String key, ThrowingParser parser) + throws MissingParameterException, ParameterParseException { String value = require(key); try { return parser.parse(value); @@ -85,7 +85,8 @@ public class RequestParameterAccessor { * @return parsed parameter value or {@code defaultValue} if absent * @throws ParameterParseException if parsing the raw value fails */ - public T optional(String key, T defaultValue, ThrowingParser parser) throws ParameterParseException { + public T optional(String key, T defaultValue, ThrowingParser parser) + throws ParameterParseException { String value = index.get(key); if (value == null) { return defaultValue; From f467b2861f5ebe2c5a062aff01a82a3741918423 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 13:27:59 +0200 Subject: [PATCH 082/104] Style: Line length --- .../server/network/parser/RequestParameterAccessor.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java index a79f7b1..0d691e5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -56,7 +56,8 @@ public class RequestParameterAccessor { try { return parser.parse(value); } catch (Exception e) { - throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); + throw new ParameterParseException( + "Error while parsing '" + key + "' with specified parser", key, e); } } @@ -95,7 +96,8 @@ public class RequestParameterAccessor { try { return parser.parse(value); } catch (Exception e) { - throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); + throw new ParameterParseException( + "Error while parsing '" + key + "' with specified parser", key, e); } } From f841eecb93de7fe690e333a7a32f96b0ca6f938d Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 14:13:29 +0200 Subject: [PATCH 083/104] Fix: disallow failure for checkstyle job for merge requests --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 04bb8bd..3c78f55 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,7 +22,7 @@ stages: .on-mr: &on-mr rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - allow_failure: true # deactivate after all issues (shown by checkstyle) have been resolved + allow_failure: false # Jobs checkstyle: @@ -48,7 +48,7 @@ checkstyle-mr: image: gradle:9.3.1-jdk25 script: - gradle checkstyleMain checkstyleTest - allow_failure: true + allow_failure: false artifacts: when: always paths: @@ -66,6 +66,7 @@ checkstyle-report: - job: checkstyle-mr artifacts: true optional: true + when: always rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' script: From f9b866fc403f3f8d67a0da585778fe2eee3945e7 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 14:15:11 +0200 Subject: [PATCH 084/104] Add: Violator dummy class to test pipeline behaviour --- .../ch/unibas/dmi/dbis/cs108/casono/server/Violator.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java new file mode 100644 index 0000000..854b34c --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server; + +public class Violator { + public void dummy() { + System.out.println("This is a disallowed sysout statement, triggering the failure of the merge request"); + } +} From 9d4afdc3e8a7a6e63016dff0d3be1d6dc26f18c6 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 14:20:01 +0200 Subject: [PATCH 085/104] Remove: Violator dummy file --- .../ch/unibas/dmi/dbis/cs108/casono/server/Violator.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java deleted file mode 100644 index 854b34c..0000000 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/Violator.java +++ /dev/null @@ -1,7 +0,0 @@ -package ch.unibas.dmi.dbis.cs108.casono.server; - -public class Violator { - public void dummy() { - System.out.println("This is a disallowed sysout statement, triggering the failure of the merge request"); - } -} From 4a4af3807a3742fb8afd0bdb37f386674c731aee Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 14:46:53 +0200 Subject: [PATCH 086/104] Ci: Enable configuration-cache via flag and warn on problems --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c78f55..eae942c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,7 +30,7 @@ checkstyle: stage: lint image: gradle:9.3.1-jdk25 script: - - gradle checkstyleMain checkstyleTest + - gradle checkstyleMain checkstyleTest --configuration-cache --configuration-cache-problems=warn allow_failure: true artifacts: when: always @@ -47,7 +47,7 @@ checkstyle-mr: stage: lint image: gradle:9.3.1-jdk25 script: - - gradle checkstyleMain checkstyleTest + - gradle checkstyleMain checkstyleTest --configuration-cache --configuration-cache-problems=warn allow_failure: false artifacts: when: always @@ -82,7 +82,7 @@ compile-check: stage: build image: gradle:9.3.1-jdk25 script: - - gradle compileTestJava + - gradle compileTestJava --configuration-cache --configuration-cache-problems=warn needs: [] rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' @@ -95,7 +95,7 @@ test: stage: test image: gradle:9.3.1-jdk25 script: - - gradle test + - gradle test --configuration-cache --configuration-cache-problems=warn artifacts: when: always reports: From d027696580b17efe5742c636853283f5bf948a56 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 14:50:42 +0200 Subject: [PATCH 087/104] Ci: Modify gradle-cache definition to fix path issue --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eae942c..ef2d1f5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,11 +6,13 @@ stages: # Reusable definitions .gradle-cache: &gradle-cache + variables: + GRADLE_USER_HOME: '$CI_PROJECT_DIR/.gradle-home' cache: key: '$CI_PROJECT_ID-gradle' paths: - .gradle/ - - ~/.gradle/caches/ + - .gradle-home/ .on-commit: &on-commit rules: From 8b8ac9ccc0fffeca9077311eddad7cd30965cb98 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:41:55 +0200 Subject: [PATCH 088/104] Chore: Move request related files into own folder --- .../casono/server/network/command/CommandHandler.java | 2 +- .../casono/server/network/command/CommandRouter.java | 3 ++- .../cs108/casono/server/network/parser/CommandParser.java | 3 +++ .../server/network/parser/CommandParserDispatcher.java | 3 +++ .../casono/server/network/parser/ProtocolParser.java | 1 + .../cs108/casono/server/network/parser/RawRequest.java | 5 ----- .../{parser => request}/MissingParameterException.java | 2 +- .../{parser => request}/ParameterParseException.java | 2 +- .../network/{parser => request}/PrimitiveRequest.java | 4 +++- .../cs108/casono/server/network/request/RawRequest.java | 7 +++++++ .../server/network/{parser => request}/Request.java | 2 +- .../network/{parser => request}/RequestContext.java | 2 +- .../{parser => request}/RequestParameterAccessor.java | 4 +++- .../network/{parser => request}/ThrowingParser.java | 2 +- .../casono/server/network/sessions/SessionReader.java | 8 ++++---- 15 files changed, 32 insertions(+), 18 deletions(-) delete mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/MissingParameterException.java (92%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/ParameterParseException.java (92%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/PrimitiveRequest.java (61%) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/Request.java (88%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/RequestContext.java (87%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/RequestParameterAccessor.java (96%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => request}/ThrowingParser.java (87%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java index 34228c7..a6cd87c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; public interface CommandHandler { void execute(T request); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java index 0badeff..97b13b4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java @@ -1,9 +1,10 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; import java.util.HashMap; import java.util.Map; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; + public class CommandRouter { private final Map, CommandHandler> handlers = new HashMap<>(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java index ae00bca..d4fbe22 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java @@ -1,5 +1,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; + /** * Parser to convert the PrimitiveRequest to a Request and performing checks for required fields and * data types diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java index 722815c..dbb5bf8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java @@ -3,6 +3,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; import java.util.HashMap; import java.util.Map; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; + /** Dispatcher all CommandParser are registered in */ public class CommandParserDispatcher { private final Map parsers = new HashMap<>(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java index 8f8b4d4..87a7495 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenClassifier; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java deleted file mode 100644 index fbbc0e5..0000000 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RawRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; - -import java.util.List; - -public record RawRequest(String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java similarity index 92% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java index 55e32fa..a13747f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; /** Exception thrown when a required parameter key is not found. */ public class MissingParameterException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java similarity index 92% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java index 97628a6..9f973ec 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; /** Exception thrown when a parameter value cannot be converted to the requested type. */ public class ParameterParseException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java similarity index 61% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java index 4135e47..d853bab 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java @@ -1,7 +1,9 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; + /** Created by the ProtocolParser to allow easy access to the request contents */ public record PrimitiveRequest( RequestContext context, String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java new file mode 100644 index 0000000..f93486a --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; + +import java.util.List; + +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; + +public record RawRequest(String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java similarity index 88% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java index 8b3d70f..f056cb8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Request.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java similarity index 87% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java index 6881885..ff57463 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestContext.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java similarity index 96% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java index 0d691e5..bd34c4c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java @@ -1,9 +1,11 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; + /** * Provides typed access to a request's parameters by indexing them by key. * diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java similarity index 87% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java index af1ec9b..d6d931f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request; /** * Functional parser interface used to convert a raw string parameter into a target type. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index ad90468..b7c6fec 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -4,12 +4,12 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RawRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Request; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestContext; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RequestContext; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; From f9519a6eb502819c97897fc5ebff2900cf213887 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:43:31 +0200 Subject: [PATCH 089/104] Chore: Move RequestParameterAccessor and related files into subfolder of request --- .../request/{ => accessor}/MissingParameterException.java | 2 +- .../network/request/{ => accessor}/ParameterParseException.java | 2 +- .../request/{ => accessor}/RequestParameterAccessor.java | 2 +- .../server/network/request/{ => accessor}/ThrowingParser.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/{ => accessor}/MissingParameterException.java (91%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/{ => accessor}/ParameterParseException.java (91%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/{ => accessor}/RequestParameterAccessor.java (98%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/{ => accessor}/ThrowingParser.java (85%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java similarity index 91% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java index a13747f..bbc04e7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/MissingParameterException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; /** Exception thrown when a required parameter key is not found. */ public class MissingParameterException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java similarity index 91% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java index 9f973ec..2bb9752 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ParameterParseException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; /** Exception thrown when a parameter value cannot be converted to the requested type. */ public class ParameterParseException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java similarity index 98% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java index bd34c4c..259883d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; import java.util.List; import java.util.Map; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java index d6d931f..90b2fcc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/ThrowingParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; /** * Functional parser interface used to convert a raw string parameter into a target type. From d4b501015829911485c8516db74e8dc618acb288 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:45:08 +0200 Subject: [PATCH 090/104] Chore: Rename Parameter to RequestParameter --- .../casono/server/network/parser/ProtocolParser.java | 8 ++++---- .../parser/{Parameter.java => RequestParameter.java} | 2 +- .../casono/server/network/request/PrimitiveRequest.java | 4 ++-- .../cs108/casono/server/network/request/RawRequest.java | 4 ++-- .../request/accessor/RequestParameterAccessor.java | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/{Parameter.java => RequestParameter.java} (73%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java index 87a7495..ca90162 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java @@ -25,7 +25,7 @@ public class ProtocolParser { Iterator iterator = tokens.iterator(); String command = readCommand(iterator); - List parameters = readParameters(iterator); + List parameters = readParameters(iterator); return new RawRequest(command, parameters); } @@ -51,8 +51,8 @@ public class ProtocolParser { * @param iterator * @return list containing all parsed parameters */ - private static List readParameters(Iterator iterator) { - List parameters = new ArrayList<>(); + private static List readParameters(Iterator iterator) { + List parameters = new ArrayList<>(); try { while (iterator.hasNext()) { @@ -66,7 +66,7 @@ public class ProtocolParser { readSeperator(iterator.next()); String value = readValue(iterator.next()); - parameters.add(new Parameter(key, value)); + parameters.add(new RequestParameter(key, value)); } } catch (NoSuchElementException e) { throw new ProtocolParserException("Ran out of tokens while reading parameter"); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Parameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java similarity index 73% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Parameter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java index fb35343..00b8016 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Parameter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java @@ -1,4 +1,4 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; /** Used in the PrimitiveRequest class to store the key of a parameter with its respective value */ -public record Parameter(String key, String value) {} +public record RequestParameter(String key, String value) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java index d853bab..71b35a2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java @@ -2,8 +2,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; /** Created by the ProtocolParser to allow easy access to the request contents */ public record PrimitiveRequest( - RequestContext context, String command, List parameters) {} + RequestContext context, String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java index f93486a..86aee86 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java @@ -2,6 +2,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; -public record RawRequest(String command, List parameters) {} +public record RawRequest(String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java index 259883d..ed95c84 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.Parameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; /** * Provides typed access to a request's parameters by indexing them by key. @@ -20,10 +20,10 @@ public class RequestParameterAccessor { * * @param parameters to use */ - public RequestParameterAccessor(List parameters) { + public RequestParameterAccessor(List parameters) { this.index = parameters.stream() - .collect(Collectors.toUnmodifiableMap(Parameter::key, Parameter::value)); + .collect(Collectors.toUnmodifiableMap(RequestParameter::key, RequestParameter::value)); } /** From 050b349638f2a883408daf6c228e80fb2c582fc3 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:50:30 +0200 Subject: [PATCH 091/104] Chore: Move ProtocolParser to 'protocol' folder for protocol-level processing --- .../server/network/{ => protocol}/parser/ProtocolParser.java | 3 ++- .../{ => protocol}/parser/ProtocolParserException.java | 2 +- .../cs108/casono/server/network/sessions/SessionReader.java | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/parser/ProtocolParser.java (95%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/parser/ProtocolParserException.java (67%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java similarity index 95% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index ca90162..99bd05f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -1,5 +1,6 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParserException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParserException.java similarity index 67% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParserException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParserException.java index e00e960..63e57a9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParserException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParserException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; public class ProtocolParserException extends RuntimeException { public ProtocolParserException(String message) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index b7c6fec..ac4d1bc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -4,8 +4,8 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParserException; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParser; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParserException; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; From 52daf4f2e05cb5304081c16010c61e3e40527290 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:52:10 +0200 Subject: [PATCH 092/104] Chore: Move CommandRouter and CommandHandler to execution subfolder in command section --- .../java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 2 +- .../server/network/command/{ => execution}/CommandHandler.java | 2 +- .../server/network/command/{ => execution}/CommandRouter.java | 2 +- .../command/{ => execution}/UnknownRequestException.java | 2 +- .../dmi/dbis/cs108/casono/server/network/sessions/Session.java | 2 +- .../cs108/casono/server/network/sessions/SessionManager.java | 2 +- .../cs108/casono/server/network/sessions/SessionReader.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/{ => execution}/CommandHandler.java (67%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/{ => execution}/CommandRouter.java (93%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/{ => execution}/UnknownRequestException.java (81%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index e76e877..6c1f5ec 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -3,7 +3,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java similarity index 67% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java index a6cd87c..e0d5524 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.command; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java similarity index 93% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java index 97b13b4..ea8c6ea 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.command; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/UnknownRequestException.java similarity index 81% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/UnknownRequestException.java index 60c7fa3..1493f25 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/UnknownRequestException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/UnknownRequestException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.command; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; public class UnknownRequestException extends RuntimeException { private final String requestName; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 3fc97e5..5e78115 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index 8dae02d..eafc0c7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index ac4d1bc..5cd9bc6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; From ed24ba7214fe9fd4d1313bb37026de76e42c2374 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 17:54:19 +0200 Subject: [PATCH 093/104] Chore: Move command parsing to 'parsing' subfolder in command section --- .../java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java | 2 +- .../network/{parser => command/parsing}/CommandParser.java | 2 +- .../{parser => command/parsing}/CommandParserDispatcher.java | 2 +- .../network/{parser => command/parsing}/RequestParameter.java | 2 +- .../{parser => command/parsing}/UnknownCommandException.java | 2 +- .../casono/server/network/protocol/parser/ProtocolParser.java | 2 +- .../cs108/casono/server/network/request/PrimitiveRequest.java | 2 +- .../dbis/cs108/casono/server/network/request/RawRequest.java | 2 +- .../network/request/accessor/RequestParameterAccessor.java | 2 +- .../dmi/dbis/cs108/casono/server/network/sessions/Session.java | 2 +- .../cs108/casono/server/network/sessions/SessionManager.java | 2 +- .../cs108/casono/server/network/sessions/SessionReader.java | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => command/parsing}/CommandParser.java (87%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => command/parsing}/CommandParserDispatcher.java (94%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => command/parsing}/RequestParameter.java (69%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{parser => command/parsing}/UnknownCommandException.java (78%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java index 6c1f5ec..5687b5b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/ServerApp.java @@ -4,9 +4,9 @@ import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserCleanupJob; import ch.unibas.dmi.dbis.cs108.casono.server.domain.user.UserRegistry; import ch.unibas.dmi.dbis.cs108.casono.server.network.NetworkManager; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionDisconnectJob; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; import java.time.Duration; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java similarity index 87% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java index d4fbe22..6907ff5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java similarity index 94% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java index dbb5bf8..1854400 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/CommandParserDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/RequestParameter.java similarity index 69% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/RequestParameter.java index 00b8016..d0ca720 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/RequestParameter.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; /** Used in the PrimitiveRequest class to store the key of a parameter with its respective value */ public record RequestParameter(String key, String value) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/UnknownCommandException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/UnknownCommandException.java similarity index 78% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/UnknownCommandException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/UnknownCommandException.java index 5048d70..0b5759b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/UnknownCommandException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/UnknownCommandException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; +package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; /** * Exception thrown when the CommandParserDispatcher has no registered handler for the provided diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index 99bd05f..862e968 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java index 71b35a2..17825b2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java @@ -2,7 +2,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; /** Created by the ProtocolParser to allow easy access to the request contents */ public record PrimitiveRequest( diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java index 86aee86..f9293b2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java @@ -2,6 +2,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.request; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; public record RawRequest(String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java index ed95c84..f46c15a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.RequestParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; /** * Provides typed access to a request's parameters by indexing them by key. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index 5e78115..ba33dd5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -1,8 +1,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java index eafc0c7..ba25cf4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionManager.java @@ -1,9 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; import java.util.Collection; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 5cd9bc6..6d941c8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -1,9 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParserException; import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; From ba6ff36ee2c801a4e99a834a044cfe1027367d89 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:00:34 +0200 Subject: [PATCH 094/104] Chore: Move ResponseBodyBuilder to 'builder' subfolder in response section --- .../cs108/casono/server/network/response/ErrorResponse.java | 1 + .../dbis/cs108/casono/server/network/response/OkResponse.java | 1 + .../dbis/cs108/casono/server/network/response/Response.java | 1 + .../cs108/casono/server/network/response/ResponseEncoder.java | 4 ++++ .../cs108/casono/server/network/response/SuccessResponse.java | 1 + .../server/network/response/{ => builder}/ResponseBlock.java | 2 +- .../server/network/response/{ => builder}/ResponseBody.java | 4 +++- .../network/response/{ => builder}/ResponseBodyBuilder.java | 2 +- .../server/network/response/{ => builder}/ResponseNode.java | 2 +- .../network/response/{ => builder}/ResponseParameter.java | 2 +- 10 files changed, 15 insertions(+), 5 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => builder}/ResponseBlock.java (83%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => builder}/ResponseBody.java (87%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => builder}/ResponseBodyBuilder.java (95%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => builder}/ResponseNode.java (73%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => builder}/ResponseParameter.java (90%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java index 602181b..77d7137 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** Response representing an error outcome for a client's request. */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java index a3f26c5..0d5288f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java index 8a3cf96..5ba94bb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** Abstract base class for all server responses sent to clients. */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java index dbe8d12..4f228a5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java @@ -1,5 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBlock; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseNode; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseParameter; + /** * Utility responsible for encoding a {@link Response} into a protocol payload string and wrapping * it into a {@link PrimitiveResponse} suitable for transmission. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java index e88913f..b901a82 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java @@ -1,5 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java similarity index 83% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java index 075abaf..d0f13f5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java similarity index 87% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java index 8c52ffc..44ad8f6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBody.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java @@ -1,7 +1,9 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; import java.util.List; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; + /** * Immutable container for the structured content of a {@link Response}. * diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java similarity index 95% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java index f6491b0..0c78770 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBodyBuilder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java similarity index 73% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java index c3af815..f9a51aa 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseNode.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; /** * Marker interface for elements that may appear in a {@link ResponseBody}. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java similarity index 90% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java index 87f599a..f537b69 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; /** * A parameter node stored in a {@link ResponseBody}. From cf0cd2666cfdae26f0be2c836baf0df2a7d7296a Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:06:43 +0200 Subject: [PATCH 095/104] Move ResponseDispatcher to 'dispatcher' subfolder in response section --- .../network/response/{ => dispatcher}/ResponseDispatcher.java | 4 +++- .../network/response/{ => dispatcher}/ResponseEncoder.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => dispatcher}/ResponseDispatcher.java (85%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/{ => dispatcher}/ResponseEncoder.java (93%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java index 57b9181..cb2172b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java @@ -1,5 +1,7 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.dispatcher; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java similarity index 93% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java index 4f228a5..f824d00 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseEncoder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java @@ -1,5 +1,7 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.response.dispatcher; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBlock; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseNode; import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseParameter; From e0b791589c499884bafff38fc1478253783306e6 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:17:11 +0200 Subject: [PATCH 096/104] Chore: Move 'request' folder into protocol section --- .../server/network/command/execution/CommandHandler.java | 2 +- .../server/network/command/execution/CommandRouter.java | 2 +- .../server/network/command/parsing/CommandParser.java | 4 ++-- .../network/command/parsing/CommandParserDispatcher.java | 4 ++-- .../server/network/protocol/parser/ProtocolParser.java | 2 +- .../network/{ => protocol}/request/PrimitiveRequest.java | 2 +- .../server/network/{ => protocol}/request/RawRequest.java | 2 +- .../server/network/{ => protocol}/request/Request.java | 2 +- .../network/{ => protocol}/request/RequestContext.java | 2 +- .../request/accessor/MissingParameterException.java | 2 +- .../request/accessor/ParameterParseException.java | 2 +- .../request/accessor/RequestParameterAccessor.java | 2 +- .../{ => protocol}/request/accessor/ThrowingParser.java | 2 +- .../casono/server/network/sessions/SessionReader.java | 8 ++++---- 14 files changed, 19 insertions(+), 19 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/PrimitiveRequest.java (81%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/RawRequest.java (72%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/Request.java (87%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/RequestContext.java (86%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/accessor/MissingParameterException.java (90%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/accessor/ParameterParseException.java (91%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/accessor/RequestParameterAccessor.java (97%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/request/accessor/ThrowingParser.java (84%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java index e0d5524..0fdae3c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandHandler.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; public interface CommandHandler { void execute(T request); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java index ea8c6ea..2fccfe9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java @@ -3,7 +3,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; import java.util.HashMap; import java.util.Map; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; public class CommandRouter { private final Map, CommandHandler> handlers = new HashMap<>(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java index 6907ff5..3a3b76f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParser.java @@ -1,7 +1,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; /** * Parser to convert the PrimitiveRequest to a Request and performing checks for required fields and diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java index 1854400..9031616 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java @@ -3,8 +3,8 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; import java.util.HashMap; import java.util.Map; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; /** Dispatcher all CommandParser are registered in */ public class CommandParserDispatcher { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index 862e968..853845f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -1,7 +1,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenClassifier; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java similarity index 81% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java index 17825b2..c31a91a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java similarity index 72% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java index f9293b2..ba0be0d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RawRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/Request.java similarity index 87% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/Request.java index f056cb8..1e618ad 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/Request.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/Request.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RequestContext.java similarity index 86% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RequestContext.java index ff57463..63816f6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/RequestContext.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RequestContext.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/MissingParameterException.java similarity index 90% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/MissingParameterException.java index bbc04e7..bda6e7e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/MissingParameterException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/MissingParameterException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor; /** Exception thrown when a required parameter key is not found. */ public class MissingParameterException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ParameterParseException.java similarity index 91% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ParameterParseException.java index 2bb9752..e6f9f1f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ParameterParseException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ParameterParseException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor; /** Exception thrown when a parameter value cannot be converted to the requested type. */ public class ParameterParseException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java similarity index 97% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java index f46c15a..082bf62 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor; import java.util.List; import java.util.Map; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ThrowingParser.java similarity index 84% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ThrowingParser.java index 90b2fcc..688304b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/request/accessor/ThrowingParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/ThrowingParser.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.request.accessor; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor; /** * Functional parser interface used to convert a raw string parameter into a target type. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 6d941c8..824385b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -6,10 +6,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParserException; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.PrimitiveRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RawRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.Request; -import ch.unibas.dmi.dbis.cs108.casono.server.network.request.RequestContext; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; From 442a846c71bd335dda93d78796a68507d07eba67 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:18:22 +0200 Subject: [PATCH 097/104] Chore: Move 'response' into protocol section --- .../{ => protocol}/response/ErrorResponse.java | 4 ++-- .../network/{ => protocol}/response/OkResponse.java | 4 ++-- .../{ => protocol}/response/PrimitiveResponse.java | 2 +- .../network/{ => protocol}/response/Response.java | 4 ++-- .../{ => protocol}/response/SuccessResponse.java | 4 ++-- .../response/builder/ResponseBlock.java | 2 +- .../response/builder/ResponseBody.java | 4 ++-- .../response/builder/ResponseBodyBuilder.java | 2 +- .../response/builder/ResponseNode.java | 2 +- .../response/builder/ResponseParameter.java | 2 +- .../response/dispatcher/ResponseDispatcher.java | 6 +++--- .../response/dispatcher/ResponseEncoder.java | 12 ++++++------ .../casono/server/network/sessions/Session.java | 2 +- .../server/network/sessions/SessionWriter.java | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/ErrorResponse.java (85%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/OkResponse.java (78%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/PrimitiveResponse.java (84%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/Response.java (90%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/SuccessResponse.java (85%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/builder/ResponseBlock.java (81%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/builder/ResponseBody.java (86%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/builder/ResponseBodyBuilder.java (95%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/builder/ResponseNode.java (71%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/builder/ResponseParameter.java (89%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/dispatcher/ResponseDispatcher.java (83%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/{ => protocol}/response/dispatcher/ResponseEncoder.java (85%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/ErrorResponse.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/ErrorResponse.java index 77d7137..1136e11 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/ErrorResponse.java @@ -1,6 +1,6 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** Response representing an error outcome for a client's request. */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/OkResponse.java similarity index 78% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/OkResponse.java index 0d5288f..f0d7cd6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/OkResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/OkResponse.java @@ -1,6 +1,6 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/PrimitiveResponse.java similarity index 84% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/PrimitiveResponse.java index 1ef7a6a..3f7ce3d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/PrimitiveResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/PrimitiveResponse.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/Response.java similarity index 90% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/Response.java index 5ba94bb..d0918fb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/Response.java @@ -1,6 +1,6 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** Abstract base class for all server responses sent to clients. */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/SuccessResponse.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/SuccessResponse.java index b901a82..3df95b9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/SuccessResponse.java @@ -1,6 +1,6 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBody; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBody; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionId; /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBlock.java similarity index 81% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBlock.java index d0f13f5..e738a27 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBlock.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBlock.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java similarity index 86% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java index 44ad8f6..fdd4a02 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBody.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java @@ -1,8 +1,8 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.Response; /** * Immutable container for the structured content of a {@link Response}. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBodyBuilder.java similarity index 95% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBodyBuilder.java index 0c78770..c05083d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseBodyBuilder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBodyBuilder.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseNode.java similarity index 71% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseNode.java index f9a51aa..b2bb118 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseNode.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseNode.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; /** * Marker interface for elements that may appear in a {@link ResponseBody}. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseParameter.java similarity index 89% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseParameter.java index f537b69..73ffbf7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/builder/ResponseParameter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseParameter.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; /** * A parameter node stored in a {@link ResponseBody}. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseDispatcher.java similarity index 83% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseDispatcher.java index cb2172b..1be2f27 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseDispatcher.java @@ -1,7 +1,7 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.dispatcher; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.Response; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.Session; import ch.unibas.dmi.dbis.cs108.casono.server.network.sessions.SessionManager; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseEncoder.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseEncoder.java index f824d00..013ddd5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/dispatcher/ResponseEncoder.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/dispatcher/ResponseEncoder.java @@ -1,10 +1,10 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.response.dispatcher; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.dispatcher; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.Response; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseBlock; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseNode; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.builder.ResponseParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.Response; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseBlock; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseNode; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder.ResponseParameter; /** * Utility responsible for encoding a {@link Response} into a protocol payload string and wrapping diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java index ba33dd5..5f58068 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/Session.java @@ -3,7 +3,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution.CommandRouter; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.CommandParserDispatcher; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; import java.time.Instant; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java index e5c3e78..c59abb3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionWriter.java @@ -1,6 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions; -import ch.unibas.dmi.dbis.cs108.casono.server.network.response.PrimitiveResponse; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.PrimitiveResponse; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.IOException; From 6e446b665ad550b17bd6f7f804898e61fb31f412 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:21:56 +0200 Subject: [PATCH 098/104] Chore: Move 'tokenizer' into protocol section --- .../network/protocol/parser/ProtocolParser.java | 11 ++++++----- .../{ => network/protocol}/tokenizer/RawToken.java | 2 +- .../protocol}/tokenizer/RawTokenType.java | 2 +- .../{ => network/protocol}/tokenizer/State.java | 2 +- .../{ => network/protocol}/tokenizer/Token.java | 2 +- .../protocol}/tokenizer/TokenClassifier.java | 2 +- .../{ => network/protocol}/tokenizer/TokenType.java | 2 +- .../{ => network/protocol}/tokenizer/Tokenizer.java | 2 +- .../protocol}/tokenizer/TokenizerException.java | 2 +- .../casono/server/network/sessions/SessionReader.java | 3 ++- .../dbis/cs108/casono/server/tokenizer/StateTest.java | 2 ++ .../server/tokenizer/TokenizerExceptionTest.java | 2 ++ 12 files changed, 20 insertions(+), 14 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/RawToken.java (65%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/RawTokenType.java (53%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/State.java (90%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/Token.java (61%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/TokenClassifier.java (98%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/TokenType.java (65%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/Tokenizer.java (98%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/TokenizerException.java (85%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index 853845f..b107ea6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -2,11 +2,12 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenClassifier; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenType; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Tokenizer; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.RawToken; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Token; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenClassifier; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenType; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Tokenizer; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawToken.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java similarity index 65% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawToken.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java index c8bc6bb..d454904 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawToken.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; /** Represents a raw (unclassified) token in the tokenizer. */ public record RawToken(RawTokenType type, String value, int line, int column) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawTokenType.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java similarity index 53% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawTokenType.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java index b37d430..309767e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/RawTokenType.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; public enum RawTokenType { WORD, diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/State.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java similarity index 90% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/State.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java index d130a52..faf7e6f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/State.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Token.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java similarity index 61% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Token.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java index 93b9026..f885eba 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Token.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; /** Represents a token in the tokenizer. */ public record Token(TokenType type, String value, int line, int column) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenClassifier.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java similarity index 98% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenClassifier.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java index cb19021..4d5c26a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenClassifier.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenType.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java similarity index 65% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenType.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java index af52b02..3496607 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenType.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; /** Enumeration of token types used in the tokenizer. */ public enum TokenType { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Tokenizer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java similarity index 98% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Tokenizer.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java index 805d05b..24920f9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/Tokenizer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java similarity index 85% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java index 0975b1d..1e3e9bf 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; /** Exception thrown during tokenization. */ public class TokenizerException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 824385b..33bc224 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -10,9 +10,10 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Primitive import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenizerException; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; -import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenizerException; + import java.io.EOFException; import java.io.IOException; import org.apache.logging.log4j.LogManager; diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java index fd1717b..b368663 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.State; + class StateTest { @Test void testConstructor() { diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java index d161b9b..c2b4178 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java @@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenizerException; + class TokenizerExceptionTest { @Test void testConstructorAndGetters() { From 86b4a6c191eb832f40c29ab2d4bf8551b3ab941d Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:23:41 +0200 Subject: [PATCH 099/104] Chore: Remove leftover TODO --- .../dmi/dbis/cs108/casono/server/domain/user/UserRegistry.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/user/UserRegistry.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/user/UserRegistry.java index 6a60877..adb1abe 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/user/UserRegistry.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/domain/user/UserRegistry.java @@ -58,7 +58,6 @@ public class UserRegistry { * * @param sessionId the session ID of the disconnected client */ - // TODO: Add to EventRegistry with DisconnectEvent public synchronized void onDisconnect(SessionId sessionId) { User user = bySessionId.remove(sessionId); if (user == null) { From 0930fbe990b7bfa02126161e9a95b8ff3bddfb08 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:26:45 +0200 Subject: [PATCH 100/104] Chore: Reflect changes to folder structure in tests --- .../server/{ => network/protocol}/tokenizer/StateTest.java | 4 +--- .../protocol}/tokenizer/TokenizerExceptionTest.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) rename src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/StateTest.java (91%) rename src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/{ => network/protocol}/tokenizer/TokenizerExceptionTest.java (76%) diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java similarity index 91% rename from src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java rename to src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java index b368663..5f0f8be 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/StateTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -6,8 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.State; - class StateTest { @Test void testConstructor() { diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java similarity index 76% rename from src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java rename to src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java index c2b4178..39ec405 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/tokenizer/TokenizerExceptionTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java @@ -1,11 +1,9 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenizerException; - class TokenizerExceptionTest { @Test void testConstructorAndGetters() { From b588f38cd5354e0b011867bb8012b213ed246ef1 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:27:17 +0200 Subject: [PATCH 101/104] Style: Apply Spotless --- .../server/network/command/execution/CommandRouter.java | 3 +-- .../network/command/parsing/CommandParserDispatcher.java | 5 ++--- .../server/network/protocol/parser/ProtocolParser.java | 1 - .../server/network/protocol/request/PrimitiveRequest.java | 3 +-- .../casono/server/network/protocol/request/RawRequest.java | 3 +-- .../request/accessor/RequestParameterAccessor.java | 7 ++++--- .../network/protocol/response/builder/ResponseBody.java | 3 +-- .../casono/server/network/sessions/SessionReader.java | 1 - 8 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java index 2fccfe9..269c6a4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/execution/CommandRouter.java @@ -1,10 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.execution; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; import java.util.HashMap; import java.util.Map; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; - public class CommandRouter { private final Map, CommandHandler> handlers = new HashMap<>(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java index 9031616..02480ac 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/command/parsing/CommandParserDispatcher.java @@ -1,10 +1,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing; -import java.util.HashMap; -import java.util.Map; - import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; +import java.util.HashMap; +import java.util.Map; /** Dispatcher all CommandParser are registered in */ public class CommandParserDispatcher { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index b107ea6..e5ab65d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -7,7 +7,6 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Token; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenClassifier; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenType; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Tokenizer; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java index c31a91a..e591a2f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/PrimitiveRequest.java @@ -1,8 +1,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; -import java.util.List; - import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; +import java.util.List; /** Created by the ProtocolParser to allow easy access to the request contents */ public record PrimitiveRequest( diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java index ba0be0d..f5033a3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/RawRequest.java @@ -1,7 +1,6 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; import java.util.List; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; - public record RawRequest(String command, List parameters) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java index 082bf62..04071e3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/request/accessor/RequestParameterAccessor.java @@ -1,11 +1,10 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.accessor; +import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; - /** * Provides typed access to a request's parameters by indexing them by key. * @@ -23,7 +22,9 @@ public class RequestParameterAccessor { public RequestParameterAccessor(List parameters) { this.index = parameters.stream() - .collect(Collectors.toUnmodifiableMap(RequestParameter::key, RequestParameter::value)); + .collect( + Collectors.toUnmodifiableMap( + RequestParameter::key, RequestParameter::value)); } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java index fdd4a02..bb783d7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/response/builder/ResponseBody.java @@ -1,8 +1,7 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.builder; -import java.util.List; - import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.response.Response; +import java.util.List; /** * Immutable container for the structured content of a {@link Response}. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index 33bc224..aa17e67 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -13,7 +13,6 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestCo import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenizerException; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; - import java.io.EOFException; import java.io.IOException; import org.apache.logging.log4j.LogManager; From 059b70648547c7aa7f9db1ac6c44b073a7a97724 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:42:05 +0200 Subject: [PATCH 102/104] Chore: Move 'tokenizer' into protocol/parser section --- .../server/network/protocol/parser/ProtocolParser.java | 10 +++++----- .../protocol/{ => parser}/tokenizer/RawToken.java | 2 +- .../protocol/{ => parser}/tokenizer/RawTokenType.java | 2 +- .../network/protocol/{ => parser}/tokenizer/State.java | 2 +- .../network/protocol/{ => parser}/tokenizer/Token.java | 2 +- .../{ => parser}/tokenizer/TokenClassifier.java | 2 +- .../protocol/{ => parser}/tokenizer/TokenType.java | 2 +- .../protocol/{ => parser}/tokenizer/Tokenizer.java | 2 +- .../{ => parser}/tokenizer/TokenizerException.java | 2 +- .../casono/server/network/sessions/SessionReader.java | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/RawToken.java (92%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/RawTokenType.java (89%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/State.java (97%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/Token.java (91%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/TokenClassifier.java (99%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/TokenType.java (91%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/Tokenizer.java (99%) rename src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/TokenizerException.java (96%) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java index e5ab65d..b3afd0c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/ProtocolParser.java @@ -1,12 +1,12 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser; import ch.unibas.dmi.dbis.cs108.casono.server.network.command.parsing.RequestParameter; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.RawToken; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.Token; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.TokenClassifier; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.TokenType; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.Tokenizer; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.RawToken; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Token; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenClassifier; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenType; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.Tokenizer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawToken.java similarity index 92% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawToken.java index d454904..1a07f35 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawToken.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawToken.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; /** Represents a raw (unclassified) token in the tokenizer. */ public record RawToken(RawTokenType type, String value, int line, int column) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawTokenType.java similarity index 89% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawTokenType.java index 309767e..15949a3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/RawTokenType.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/RawTokenType.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; public enum RawTokenType { WORD, diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/State.java similarity index 97% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/State.java index faf7e6f..2848d99 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/State.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/State.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Token.java similarity index 91% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Token.java index f885eba..c99d3cd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Token.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Token.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; /** Represents a token in the tokenizer. */ public record Token(TokenType type, String value, int line, int column) {} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenClassifier.java similarity index 99% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenClassifier.java index 4d5c26a..330dcbb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenClassifier.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenClassifier.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenType.java similarity index 91% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenType.java index 3496607..5096da9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenType.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenType.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; /** Enumeration of token types used in the tokenizer. */ public enum TokenType { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Tokenizer.java similarity index 99% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Tokenizer.java index 24920f9..843edf9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/Tokenizer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/Tokenizer.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; import java.util.List; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerException.java similarity index 96% rename from src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerException.java index 1e3e9bf..c514a1e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerException.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerException.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; /** Exception thrown during tokenization. */ public class TokenizerException extends RuntimeException { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java index aa17e67..81589a0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/sessions/SessionReader.java @@ -6,11 +6,11 @@ import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent; import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParser; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.ProtocolParserException; +import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer.TokenizerException; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.PrimitiveRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RawRequest; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.Request; import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.request.RequestContext; -import ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer.TokenizerException; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.EOFException; From 2203f804904a0a7f1e20a0c30b9f07c2ecad0f2c Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Mon, 30 Mar 2026 18:42:19 +0200 Subject: [PATCH 103/104] Chore: Reflect path changes for tests --- .../network/protocol/{ => parser}/tokenizer/StateTest.java | 2 +- .../protocol/{ => parser}/tokenizer/TokenizerExceptionTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/StateTest.java (98%) rename src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/{ => parser}/tokenizer/TokenizerExceptionTest.java (96%) diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/StateTest.java similarity index 98% rename from src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java rename to src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/StateTest.java index 5f0f8be..19832cc 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/StateTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/StateTest.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerExceptionTest.java similarity index 96% rename from src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java rename to src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerExceptionTest.java index 39ec405..bb6bc58 100644 --- a/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/tokenizer/TokenizerExceptionTest.java +++ b/src/test/java/ch/unibas/dmi/dbis/cs108/casono/server/network/protocol/parser/tokenizer/TokenizerExceptionTest.java @@ -1,4 +1,4 @@ -package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.tokenizer; +package ch.unibas.dmi.dbis.cs108.casono.server.network.protocol.parser.tokenizer; import static org.junit.jupiter.api.Assertions.assertEquals; From 45a6b87303f71b8a92307738114ae25b9a0c875c Mon Sep 17 00:00:00 2001 From: Jona Walpert Date: Mon, 30 Mar 2026 23:33:48 +0200 Subject: [PATCH 104/104] Chore: Add build-cs108 Gradle task and javadocJar --- build.gradle | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/build.gradle b/build.gradle index a7f3f9e..4360c82 100644 --- a/build.gradle +++ b/build.gradle @@ -108,3 +108,17 @@ tasks.register('fatJar', Jar) { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }) } + + tasks.register('javadocJar', Jar) { + group = 'build' + description = 'Assembles a Javadoc JAR.' + dependsOn tasks.named('javadoc') + archiveClassifier = 'javadoc' + from(tasks.javadoc.destinationDir) + } + + tasks.register('build-cs108') { + group = 'build' + description = 'Produces executable JAR and Javadoc JAR for CS108.' + dependsOn tasks.named('fatJar'), tasks.named('javadocJar') + }