diff options
Diffstat (limited to 'src/uk/org/ury/common/protocol')
5 files changed, 185 insertions, 0 deletions
diff --git a/src/uk/org/ury/common/protocol/Directive.java b/src/uk/org/ury/common/protocol/Directive.java new file mode 100644 index 0000000..e1edd98 --- /dev/null +++ b/src/uk/org/ury/common/protocol/Directive.java @@ -0,0 +1,18 @@ +/** + * + */ +package uk.org.ury.common.protocol; + +/** + * Directives supported by the protocol. + * + * @author Matt Windsor + */ + +public enum Directive + { + INFO, // Information string (can usually be ignored) + ITEMS, // Item + STATUS, // Status code (from the enum Status) + REASON; // Error reason + } diff --git a/src/uk/org/ury/common/protocol/ProtocolUtils.java b/src/uk/org/ury/common/protocol/ProtocolUtils.java new file mode 100644 index 0000000..8686eb7 --- /dev/null +++ b/src/uk/org/ury/common/protocol/ProtocolUtils.java @@ -0,0 +1,85 @@ +/** + * + */ +package uk.org.ury.common.protocol; + +import java.util.Map; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import uk.org.ury.common.protocol.exceptions.DecodeFailureException; +import uk.org.ury.common.protocol.exceptions.InvalidMessageException; + +/** + * Utilities for converting between strings encoded in the response protocol and + * collections of items, as well as validating and unpicking protocol messages. + * + * @author Matt Windsor + * + */ + +public class ProtocolUtils { + /** + * Encode a key-value map into a protocol string. + * + * The map can contain strings, lists and other maps. Other types may be + * accepted by the underlying encoding engine, but the above types are the + * only ones explicitly accepted. + * + * @param items + * The key-value map of items, which should contain strings, + * lists and maps. The keys of any map should be protocol + * directives. + * + * @return A string containing the encoded representation of the map. + */ + public static String encode(Map<String, Object> items) { + return JSONValue.toJSONString(items); + } + + /** + * Decode a protocol string into a key-value map. + * + * @param string + * The string to decode. + * + * @return A key-value map mapping directives to strings, lists and maps. + * + * @throws DecodeFailureException + * if the decoding engine returns something other than a map. + */ + public static Map<?, ?> decode(String string) throws DecodeFailureException { + Object result = JSONValue.parse(string); + + if (result instanceof JSONObject) + return (JSONObject) result; + else + throw new DecodeFailureException("Result not a map."); + } + + /** + * Check if a response is flagged as having OK status. + * + * @param response + * The response message, as a key-value map (eg in decoded + * format). + * + * @return true if the response is flagged with OK status, false if not (eg + * ERROR status). + * + * @throws InvalidMessageException + * if the response is invalid (eg the status is missing). + */ + public static boolean responseIsOK(Map<?, ?> response) + throws InvalidMessageException { + if (response.containsKey(Directive.STATUS.toString()) == false) + throw new InvalidMessageException("No status line in response."); + + if ((response.get(Directive.STATUS.toString()) instanceof String) == false) + throw new InvalidMessageException("Status is not a string."); + + return (((String) response.get(Directive.STATUS.toString())) + .equals(Status.OK.toString())); + } +} diff --git a/src/uk/org/ury/common/protocol/Status.java b/src/uk/org/ury/common/protocol/Status.java new file mode 100644 index 0000000..b424fc9 --- /dev/null +++ b/src/uk/org/ury/common/protocol/Status.java @@ -0,0 +1,17 @@ +/** + * + */ +package uk.org.ury.common.protocol; + + +/** + * Statuses that can follow the STATUS directory. + * + * @author Matt Windsor + */ + +public enum Status + { + OK, // The request was processed OK; response should be valid + ERROR // An error occurred; message provided as REASON directive + } diff --git a/src/uk/org/ury/common/protocol/exceptions/DecodeFailureException.java b/src/uk/org/ury/common/protocol/exceptions/DecodeFailureException.java new file mode 100644 index 0000000..978ca7b --- /dev/null +++ b/src/uk/org/ury/common/protocol/exceptions/DecodeFailureException.java @@ -0,0 +1,32 @@ +/** + * + */ +package uk.org.ury.common.protocol.exceptions; + + +/** + * Exception thrown when the protocol decoder fails. + * + * @author Matt Windsor + */ + +public class DecodeFailureException extends Exception +{ + /** + * + */ + private static final long serialVersionUID = -3972492943653273528L; + + + /** + * Construct a new DecodeFailureException with a reason. + * + * @param reason The reason for throwing the exception. + */ + + public + DecodeFailureException (String reason) + { + super (reason); + } +} diff --git a/src/uk/org/ury/common/protocol/exceptions/InvalidMessageException.java b/src/uk/org/ury/common/protocol/exceptions/InvalidMessageException.java new file mode 100644 index 0000000..739b501 --- /dev/null +++ b/src/uk/org/ury/common/protocol/exceptions/InvalidMessageException.java @@ -0,0 +1,33 @@ +/** + * + */ +package uk.org.ury.common.protocol.exceptions; + + +/** + * Generic exception thrown when a protocol function cannot process a + * message due to an issue with the message. + * + * @author Matt Windsor + */ + +public class InvalidMessageException extends Exception +{ + /** + * + */ + private static final long serialVersionUID = -3972492943653273528L; + + + /** + * Construct a new InvalidMessageException with a reason. + * + * @param reason The reason for throwing the exception. + */ + + public + InvalidMessageException (String reason) + { + super (reason); + } +} |