From 9c3f62db243e9848501ee96bba89a1db412f3a87 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sun, 15 Mar 2026 15:18:38 +0100 Subject: [PATCH 1/5] Add: PrimitiveRequest created by ProtocolParser containing a list of Parameter objects --- .../dbis/cs108/casono/server/network/parser/Parameter.java | 4 ++++ .../casono/server/network/parser/PrimitiveRequest.java | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Parameter.java create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java 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/Parameter.java new file mode 100644 index 0000000..fb35343 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/Parameter.java @@ -0,0 +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) {} 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 new file mode 100644 index 0000000..ccd8d77 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/PrimitiveRequest.java @@ -0,0 +1,6 @@ +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(String command, List parameters) {} -- 2.52.0 From aa508dfd6cda06e3fdae74c9a01b572c0bdde280 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sun, 15 Mar 2026 16:00:00 +0100 Subject: [PATCH 2/5] Add: Exception thrown while parsing tokens --- .../server/network/parser/ProtocolParserException.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParserException.java 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/parser/ProtocolParserException.java new file mode 100644 index 0000000..e00e960 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParserException.java @@ -0,0 +1,7 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +public class ProtocolParserException extends RuntimeException { + public ProtocolParserException(String message) { + super(message); + } +} -- 2.52.0 From 7ca0bcc3e0782ec39fee0969be731d676c545a69 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sun, 15 Mar 2026 16:06:04 +0100 Subject: [PATCH 3/5] Add: Implement ProtocolParser to parse RawPacket into PrimitiveRequest --- .../server/network/parser/ProtocolParser.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java 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 new file mode 100644 index 0000000..4bd9e2a --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ProtocolParser.java @@ -0,0 +1,110 @@ +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; +import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenType; +import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Tokenizer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/** ProtocolParser, used to parse RawPacket into a PrimitiveRequest */ +public class ProtocolParser { + /** + * Parses the payload of the provided RawPacket + * + * @param packet the RawPacket containing the recieved data + * @return created PrimitiveRequest + */ + public static PrimitiveRequest parse(RawPacket packet) { + List rawTokens = Tokenizer.tokenize(packet.payload()); + List tokens = TokenClassifier.classify(rawTokens); + + Iterator iterator = tokens.iterator(); + String command = readCommand(iterator); + List parameters = readParameters(iterator); + + return new PrimitiveRequest(command, parameters); + } + + /** + * Reads the first token, which is ensured to be the command of the request + * + * @param iterator + * @return read command + */ + private static String readCommand(Iterator iterator) { + Token token = iterator.next(); + if (token.type() != TokenType.COMMAND) { + throw new ProtocolParserException("Expected COMMAND got " + token.type()); + } + + return token.value(); + } + + /** + * Iterates over the remaining tokens, calling helperfunctions to validate token type + * + * @param iterator + * @return list containing all parsed parameters + */ + private static List readParameters(Iterator iterator) { + List parameters = new ArrayList<>(); + + try { + while (iterator.hasNext()) { + Token nextToken = iterator.next(); + + if (nextToken.type() == TokenType.EOF) { + break; + } + + String key = readKey(nextToken); + readSeperator(iterator.next()); + String value = readValue(iterator.next()); + + parameters.add(new Parameter(key, value)); + } + } catch (NoSuchElementException e) { + throw new ProtocolParserException("Ran out of tokens while reading parameter"); + } + + return parameters; + } + + /** + * @param token the current token + * @return + */ + private static String readKey(Token token) { + if (token.type() != TokenType.KEY) { + throw new ProtocolParserException("Expected KEY got " + token.type()); + } + + return token.value(); + } + + /** + * @param token the current token + */ + private static void readSeperator(Token token) { + if (token.type() != TokenType.SEPARATOR) { + throw new ProtocolParserException("Expected SEPARATOR got " + token.type()); + } + } + + /** + * @param token the current token + * @return + */ + private static String readValue(Token token) { + if (token.type() != TokenType.VALUE) { + throw new ProtocolParserException("Expected VALUE got " + token.type()); + } + + return token.value(); + } +} -- 2.52.0 From a5f2ac635d47894e9adf45c4829ab59eb36d9b81 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sun, 15 Mar 2026 16:08:48 +0100 Subject: [PATCH 4/5] Add: RequestId to PrimitiveRequest --- .../cs108/casono/server/network/parser/PrimitiveRequest.java | 2 +- .../dbis/cs108/casono/server/network/parser/ProtocolParser.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 ccd8d77..4ac06de 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,4 @@ 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(String command, List parameters) {} +public record PrimitiveRequest(int requestId, String command, List parameters) {} 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 4bd9e2a..acb48a0 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 @@ -27,7 +27,7 @@ public class ProtocolParser { String command = readCommand(iterator); List parameters = readParameters(iterator); - return new PrimitiveRequest(command, parameters); + return new PrimitiveRequest(packet.requestId(), command, parameters); } /** -- 2.52.0 From 8f7c92684b8527e2a29f550d46cb5fad089f41b2 Mon Sep 17 00:00:00 2001 From: Lars Simon Winzer Date: Sun, 15 Mar 2026 16:12:14 +0100 Subject: [PATCH 5/5] Add: Use ProtocolParser in Session --- .../cs108/casono/server/network/sessions/Session.java | 9 ++++++++- 1 file changed, 8 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 3ed8f88..97e3943 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 @@ -2,6 +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.transport.RawPacket; import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer; import java.io.EOFException; import java.io.IOException; @@ -64,7 +67,11 @@ public class Session implements Runnable { public void run() { while (running) { try { - logger.debug("Recieved: {}", transport.read()); + 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)); -- 2.52.0