@@ -0,0 +1,2985 @@
+package robottables;%0A%0Apublic class Message %7B%0A%0A    public class Type %7B%0A%0A        public final static int INVALID = 0;%0A        public final static int QUERY = 1;%0A        public final static int ACK = 2;%0A        public final static int NAK = 3;%0A        public final static int PUBLISH_ADMIN = 4;%0A        public final static int DELETE_ADMIN = 5;%0A        public final static int PUBLISH_USER = 6;%0A        public final static int DELETE_USER = 7;%0A        public final static int UPDATE = 8;%0A        public final static int REQUEST = 9;%0A%0A        public final static int HIGHEST = REQUEST;%0A        public final static int LOWEST = QUERY;%0A    %7D%0A%0A    private int type;%0A    private String table;%0A    private String key;%0A    private String value;%0A%0A    public Message(int type, String table, String key, String value) %7B%0A        if (type %3C Type.LOWEST %7C%7C type %3E Type.HIGHEST) %7B%0A            throw new IllegalArgumentException(%22Invalid message type%22);%0A        %7D%0A        if (table == null %7C%7C table.length() %3C 1) %7B%0A            throw new IllegalArgumentException(%22Invalid table name%22);%0A        %7D%0A        if (key == null %7C%7C key.length() %3C 1) %7B%0A            throw new IllegalArgumentException(%22Invalid key name%22);%0A        %7D%0A        if (value == null) %7B%0A            value = %22%22;%0A        %7D%0A%0A        this.type = type;%0A        this.table = table;%0A        this.key = key;%0A        this.value = value;%0A    %7D%0A%0A    public Message(String raw) %7B%0A        parse(raw);%0A    %7D%0A%0A    @Override%0A    public String toString() %7B%0A        return String.valueOf(type) + '%5C0' + table + '%5C0' + key + '%5C0' + value;%0A    %7D%0A%0A    private void parse(String raw) %7B%0A        // Parsing%0A        int tableOffset = raw.indexOf('%5C0') + 1;%0A        int keyOffset = raw.indexOf('%5C0', tableOffset) + 1;%0A        int valueOffset = raw.indexOf('%5C0', keyOffset) + 1;%0A        if (tableOffset %3C= 0 %7C%7C keyOffset %3C= tableOffset %7C%7C valueOffset %3C= keyOffset) %7B%0A            throw new IllegalArgumentException(%22Invalid message: Bad delimiter count%22);%0A        %7D%0A%0A        // Extraction%0A        try %7B%0A            type = Integer.parseInt(raw.substring(0, tableOffset - 1));%0A        %7D catch (NumberFormatException ex) %7B%0A            type = Type.INVALID;%0A        %7D%0A        table = raw.substring(tableOffset, keyOffset - 1);%0A        key = raw.substring(keyOffset, valueOffset - 1);%0A        value = raw.substring(valueOffset);%0A%0A        // Validation%0A        if (type %3C Type.LOWEST %7C%7C type %3E Type.HIGHEST) %7B%0A            throw new IllegalArgumentException(%22Invalid message: Bad type%22);%0A        %7D%0A        if (table.length() %3C 1) %7B%0A            throw new IllegalArgumentException(%22Invalid message: Bad table%22);%0A        %7D%0A        if (key.length() %3C 1) %7B%0A            throw new IllegalArgumentException(%22Invalid message: Bad key%22);%0A        %7D%0A    %7D%0A%0A    public int getType() %7B%0A        return type;%0A    %7D%0A%0A    public String getTable() %7B%0A        return table;%0A    %7D%0A%0A    public String getKey() %7B%0A        return key;%0A    %7D%0A%0A    public String getValue() %7B%0A        return value;%0A    %7D%0A%7D%0A

Define a message object including parsing, string generation and validation