* @return converted value (does not contain JSON types) | * @return converted value (does not contain JSON types) | ||||
*/ | */ | ||||
public static Object convertValue(JSONArray value, VPaintableMap idMapper) { | public static Object convertValue(JSONArray value, VPaintableMap idMapper) { | ||||
return convertValue( | |||||
((JSONString) value.get(0)).stringValue().charAt(0), | |||||
return convertValue(((JSONString) value.get(0)).stringValue(), | |||||
value.get(1), idMapper); | value.get(1), idMapper); | ||||
} | } | ||||
private static Object convertValue(char variableType, Object value, | |||||
private static Object convertValue(String variableType, Object value, | |||||
VPaintableMap idMapper) { | VPaintableMap idMapper) { | ||||
Object val = null; | Object val = null; | ||||
// TODO type checks etc. | // TODO type checks etc. | ||||
switch (variableType) { | |||||
case JsonEncoder.VTYPE_ARRAY: | |||||
if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) { | |||||
val = convertArray((JSONArray) value, idMapper); | val = convertArray((JSONArray) value, idMapper); | ||||
break; | |||||
case JsonEncoder.VTYPE_MAP: | |||||
} else if (JsonEncoder.VTYPE_MAP.equals(variableType)) { | |||||
val = convertMap((JSONObject) value, idMapper); | val = convertMap((JSONObject) value, idMapper); | ||||
break; | |||||
case JsonEncoder.VTYPE_STRINGARRAY: | |||||
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) { | |||||
val = convertStringArray((JSONArray) value); | val = convertStringArray((JSONArray) value); | ||||
break; | |||||
case JsonEncoder.VTYPE_STRING: | |||||
} else if (JsonEncoder.VTYPE_STRING.equals(variableType)) { | |||||
val = ((JSONString) value).stringValue(); | val = ((JSONString) value).stringValue(); | ||||
break; | |||||
case JsonEncoder.VTYPE_INTEGER: | |||||
} else if (JsonEncoder.VTYPE_INTEGER.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Integer.valueOf(String.valueOf(value)); | val = Integer.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_LONG: | |||||
} else if (JsonEncoder.VTYPE_LONG.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Long.valueOf(String.valueOf(value)); | val = Long.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_FLOAT: | |||||
} else if (JsonEncoder.VTYPE_FLOAT.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Float.valueOf(String.valueOf(value)); | val = Float.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_DOUBLE: | |||||
} else if (JsonEncoder.VTYPE_DOUBLE.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Double.valueOf(String.valueOf(value)); | val = Double.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_BOOLEAN: | |||||
} else if (JsonEncoder.VTYPE_BOOLEAN.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Boolean.valueOf(String.valueOf(value)); | val = Boolean.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_PAINTABLE: | |||||
} else if (JsonEncoder.VTYPE_PAINTABLE.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = idMapper.getPaintable(String.valueOf(value)); | val = idMapper.getPaintable(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_SHAREDSTATE: | |||||
} else if (JsonEncoder.VTYPE_SHAREDSTATE.equals(variableType)) { | |||||
val = convertMap((JSONObject) value, idMapper); | val = convertMap((JSONObject) value, idMapper); | ||||
// TODO convert to a SharedState instance | // TODO convert to a SharedState instance | ||||
break; | |||||
} | } | ||||
return val; | return val; |
*/ | */ | ||||
public class JsonEncoder { | public class JsonEncoder { | ||||
public static final char VTYPE_PAINTABLE = 'p'; | |||||
public static final char VTYPE_BOOLEAN = 'b'; | |||||
public static final char VTYPE_DOUBLE = 'd'; | |||||
public static final char VTYPE_FLOAT = 'f'; | |||||
public static final char VTYPE_LONG = 'l'; | |||||
public static final char VTYPE_INTEGER = 'i'; | |||||
public static final char VTYPE_STRING = 's'; | |||||
public static final char VTYPE_ARRAY = 'a'; | |||||
public static final char VTYPE_STRINGARRAY = 'c'; | |||||
public static final char VTYPE_MAP = 'm'; | |||||
public static final String VTYPE_PAINTABLE = "p"; | |||||
public static final String VTYPE_BOOLEAN = "b"; | |||||
public static final String VTYPE_DOUBLE = "d"; | |||||
public static final String VTYPE_FLOAT = "f"; | |||||
public static final String VTYPE_LONG = "l"; | |||||
public static final String VTYPE_INTEGER = "i"; | |||||
public static final String VTYPE_STRING = "s"; | |||||
public static final String VTYPE_ARRAY = "a"; | |||||
public static final String VTYPE_STRINGARRAY = "c"; | |||||
public static final String VTYPE_MAP = "m"; | |||||
// TODO this will be replaced by the shared state class name | // TODO this will be replaced by the shared state class name | ||||
public static final char VTYPE_SHAREDSTATE = 't'; | |||||
public static final String VTYPE_SHAREDSTATE = "t"; | |||||
// TODO is this needed? | // TODO is this needed? | ||||
public static final char VTYPE_UNDEFINED = 'u'; | |||||
public static final String VTYPE_UNDEFINED = "u"; | |||||
/** | /** | ||||
* Encode a value to a JSON representation for transport from the client to | * Encode a value to a JSON representation for transport from the client to | ||||
} | } | ||||
} | } | ||||
private static JSONValue combineTypeAndValue(char type, JSONValue value) { | |||||
private static JSONValue combineTypeAndValue(String type, JSONValue value) { | |||||
JSONArray outerArray = new JSONArray(); | JSONArray outerArray = new JSONArray(); | ||||
outerArray.set(0, new JSONString(String.valueOf(type))); | |||||
outerArray.set(0, new JSONString(type)); | |||||
outerArray.set(1, value); | outerArray.set(1, value); | ||||
return outerArray; | return outerArray; | ||||
} | } | ||||
private static char getTransportType(Object value) { | |||||
private static String getTransportType(Object value) { | |||||
if (value instanceof String) { | if (value instanceof String) { | ||||
return VTYPE_STRING; | return VTYPE_STRING; | ||||
} else if (value instanceof VPaintable) { | } else if (value instanceof VPaintable) { |
*/ | */ | ||||
public class JsonCodec implements Serializable { | public class JsonCodec implements Serializable { | ||||
private static Map<Class<?>, String> typeToTransportType = new HashMap<Class<?>, String>(); | |||||
static { | |||||
registerType(String.class, JsonEncoder.VTYPE_STRING); | |||||
registerType(Paintable.class, JsonEncoder.VTYPE_PAINTABLE); | |||||
registerType(Boolean.class, JsonEncoder.VTYPE_BOOLEAN); | |||||
registerType(Integer.class, JsonEncoder.VTYPE_INTEGER); | |||||
registerType(Float.class, JsonEncoder.VTYPE_FLOAT); | |||||
registerType(Double.class, JsonEncoder.VTYPE_DOUBLE); | |||||
registerType(Long.class, JsonEncoder.VTYPE_LONG); | |||||
// transported as string representation | |||||
registerType(Enum.class, JsonEncoder.VTYPE_STRING); | |||||
registerType(String[].class, JsonEncoder.VTYPE_STRINGARRAY); | |||||
registerType(Object[].class, JsonEncoder.VTYPE_ARRAY); | |||||
registerType(Map.class, JsonEncoder.VTYPE_MAP); | |||||
} | |||||
private static void registerType(Class<?> type, String transportType) { | |||||
typeToTransportType.put(type, transportType); | |||||
} | |||||
/** | /** | ||||
* Convert a JSON array with two elements (type and value) into a | * Convert a JSON array with two elements (type and value) into a | ||||
* server-side type, recursively if necessary. | * server-side type, recursively if necessary. | ||||
*/ | */ | ||||
public static Object convertVariableValue(JSONArray value, | public static Object convertVariableValue(JSONArray value, | ||||
PaintableIdMapper idMapper) throws JSONException { | PaintableIdMapper idMapper) throws JSONException { | ||||
return convertVariableValue(value.getString(0).charAt(0), value.get(1), | |||||
idMapper); | |||||
return convertVariableValue(value.getString(0), value.get(1), idMapper); | |||||
} | } | ||||
private static Object convertVariableValue(char variableType, Object value, | |||||
PaintableIdMapper idMapper) throws JSONException { | |||||
private static Object convertVariableValue(String variableType, | |||||
Object value, PaintableIdMapper idMapper) throws JSONException { | |||||
Object val = null; | Object val = null; | ||||
// TODO type checks etc. | // TODO type checks etc. | ||||
switch (variableType) { | |||||
case JsonEncoder.VTYPE_ARRAY: | |||||
if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) { | |||||
val = convertArray((JSONArray) value, idMapper); | val = convertArray((JSONArray) value, idMapper); | ||||
break; | |||||
case JsonEncoder.VTYPE_MAP: | |||||
} else if (JsonEncoder.VTYPE_MAP.equals(variableType)) { | |||||
val = convertMap((JSONObject) value, idMapper); | val = convertMap((JSONObject) value, idMapper); | ||||
break; | |||||
case JsonEncoder.VTYPE_STRINGARRAY: | |||||
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) { | |||||
val = convertStringArray((JSONArray) value); | val = convertStringArray((JSONArray) value); | ||||
break; | |||||
case JsonEncoder.VTYPE_STRING: | |||||
} else if (JsonEncoder.VTYPE_STRING.equals(variableType)) { | |||||
val = value; | val = value; | ||||
break; | |||||
case JsonEncoder.VTYPE_INTEGER: | |||||
} else if (JsonEncoder.VTYPE_INTEGER.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Integer.valueOf(String.valueOf(value)); | val = Integer.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_LONG: | |||||
} else if (JsonEncoder.VTYPE_LONG.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Long.valueOf(String.valueOf(value)); | val = Long.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_FLOAT: | |||||
} else if (JsonEncoder.VTYPE_FLOAT.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Float.valueOf(String.valueOf(value)); | val = Float.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_DOUBLE: | |||||
} else if (JsonEncoder.VTYPE_DOUBLE.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Double.valueOf(String.valueOf(value)); | val = Double.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_BOOLEAN: | |||||
} else if (JsonEncoder.VTYPE_BOOLEAN.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = Boolean.valueOf(String.valueOf(value)); | val = Boolean.valueOf(String.valueOf(value)); | ||||
break; | |||||
case JsonEncoder.VTYPE_PAINTABLE: | |||||
} else if (JsonEncoder.VTYPE_PAINTABLE.equals(variableType)) { | |||||
// TODO handle properly | // TODO handle properly | ||||
val = idMapper.getPaintable(String.valueOf(value)); | val = idMapper.getPaintable(String.valueOf(value)); | ||||
break; | |||||
} | } | ||||
return val; | return val; | ||||
return jsonMap; | return jsonMap; | ||||
} | } | ||||
private static JSONArray combineTypeAndValue(char type, Object value) { | |||||
private static JSONArray combineTypeAndValue(String type, Object value) { | |||||
JSONArray outerArray = new JSONArray(); | JSONArray outerArray = new JSONArray(); | ||||
outerArray.put(String.valueOf(type)); | |||||
outerArray.put(type); | |||||
outerArray.put(value); | outerArray.put(value); | ||||
return outerArray; | return outerArray; | ||||
} | } | ||||
private static char getTransportType(Object value) { | |||||
if (value instanceof String) { | |||||
return JsonEncoder.VTYPE_STRING; | |||||
} else if (value instanceof Paintable) { | |||||
return JsonEncoder.VTYPE_PAINTABLE; | |||||
} else if (value instanceof Boolean) { | |||||
return JsonEncoder.VTYPE_BOOLEAN; | |||||
} else if (value instanceof Integer) { | |||||
return JsonEncoder.VTYPE_INTEGER; | |||||
} else if (value instanceof Float) { | |||||
return JsonEncoder.VTYPE_FLOAT; | |||||
} else if (value instanceof Double) { | |||||
return JsonEncoder.VTYPE_DOUBLE; | |||||
} else if (value instanceof Long) { | |||||
return JsonEncoder.VTYPE_LONG; | |||||
} else if (value instanceof Enum) { | |||||
// transported as string representation | |||||
return JsonEncoder.VTYPE_STRING; | |||||
} else if (value instanceof String[]) { | |||||
return JsonEncoder.VTYPE_STRINGARRAY; | |||||
} else if (value instanceof Object[]) { | |||||
return JsonEncoder.VTYPE_ARRAY; | |||||
} else if (value instanceof Map) { | |||||
return JsonEncoder.VTYPE_MAP; | |||||
private static String getTransportType(Object value) { | |||||
if (null == value) { | |||||
return JsonEncoder.VTYPE_UNDEFINED; | |||||
} | |||||
String transportType = typeToTransportType.get(value.getClass()); | |||||
if (null != transportType) { | |||||
return transportType; | |||||
} | } | ||||
// TODO throw exception? | // TODO throw exception? | ||||
return JsonEncoder.VTYPE_UNDEFINED; | return JsonEncoder.VTYPE_UNDEFINED; |