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..602181b --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ErrorResponse.java @@ -0,0 +1,34 @@ +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 { + /** + * 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/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());
+ }
+}
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
new file mode 100644
index 0000000..8a3cf96
--- /dev/null
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/Response.java
@@ -0,0 +1,58 @@
+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;
+ }
+}
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..075abaf
--- /dev/null
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseBlock.java
@@ -0,0 +1,12 @@
+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 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 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 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
new file mode 100644
index 0000000..87f599a
--- /dev/null
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/ResponseParameter.java
@@ -0,0 +1,23 @@
+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
new file mode 100644
index 0000000..e88913f
--- /dev/null
+++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/response/SuccessResponse.java
@@ -0,0 +1,34 @@
+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";
+ }
+}