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..55e32fa --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/MissingParameterException.java @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..97628a6 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ParameterParseException.java @@ -0,0 +1,27 @@ +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, 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 new file mode 100644 index 0000000..a79f7b1 --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/RequestParameterAccessor.java @@ -0,0 +1,111 @@ +package ch.unibas.dmi.dbis.cs108.casono.server.network.parser; + +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(Parameter::key, Parameter::value)); + } + + /** + * 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) { + throw new MissingParameterException( + "Required parameter with key '" + key + "' is missing.", key); + } + 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 { + return parser.parse(value); + } catch (Exception e) { + throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); + } + } + + /** + * 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) { + return defaultValue; + } + 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) { + return defaultValue; + } + + try { + return parser.parse(value); + } catch (Exception e) { + throw new ParameterParseException("Error while parsing '" + key + "' with specified parser", key, e); + } + } + + /** + * 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 new file mode 100644 index 0000000..af1ec9b --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/casono/server/network/parser/ThrowingParser.java @@ -0,0 +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; +}