package com.vaadin.terminal.gwt.client.communication;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
public static final String VTYPE_STRINGARRAY = "S";
public static final String VTYPE_MAP = "m";
public static final String VTYPE_LIST = "L";
+ public static final String VTYPE_SET = "q";
public static final String VTYPE_NULL = "n";
/**
return combineTypeAndValue(VTYPE_BOOLEAN,
JSONBoolean.getInstance((Boolean) value));
} else if (value instanceof Object[]) {
- Object[] array = (Object[]) value;
- JSONArray jsonArray = new JSONArray();
- for (int i = 0; i < array.length; ++i) {
- // TODO handle object graph loops?
- jsonArray.set(i, encode(array[i], connectorMap, connection));
- }
- return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
+ return encodeObjectArray((Object[]) value, connectorMap, connection);
} else if (value instanceof Map) {
Map<String, Object> map = (Map<String, Object>) value;
JSONObject jsonMap = new JSONObject();
Connector connector = (Connector) value;
return combineTypeAndValue(VTYPE_CONNECTOR, new JSONString(
connector.getConnectorId()));
+ } else if (value instanceof Collection) {
+ return encodeCollection((Collection) value, connectorMap,
+ connection);
} else {
String transportType = getTransportType(value);
if (transportType != null) {
}
}
+ private static JSONValue encodeObjectArray(Object[] array,
+ ConnectorMap connectorMap, ApplicationConnection connection) {
+ JSONArray jsonArray = new JSONArray();
+ for (int i = 0; i < array.length; ++i) {
+ // TODO handle object graph loops?
+ jsonArray.set(i, encode(array[i], connectorMap, connection));
+ }
+ return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
+ }
+
+ private static JSONValue encodeCollection(Collection collection,
+ ConnectorMap connectorMap, ApplicationConnection connection) {
+ JSONArray jsonArray = new JSONArray();
+ int idx = 0;
+ for (Object o : collection) {
+ JSONValue encodedObject = encode(o, connectorMap, connection);
+ jsonArray.set(idx++, encodedObject);
+ }
+ if (collection instanceof Set) {
+ return combineTypeAndValue(VTYPE_SET, jsonArray);
+ } else if (collection instanceof List) {
+ return combineTypeAndValue(VTYPE_LIST, jsonArray);
+ } else {
+ throw new RuntimeException("Unsupport collection type: "
+ + collection.getClass().getName());
+ }
+
+ }
+
private static JSONValue combineTypeAndValue(String type, JSONValue value) {
JSONArray outerArray = new JSONArray();
outerArray.set(0, new JSONString(type));
return VTYPE_LONG;
} else if (value instanceof List) {
return VTYPE_LIST;
+ } else if (value instanceof Set) {
+ return VTYPE_SET;
} else if (value instanceof Enum) {
return VTYPE_STRING; // transported as string representation
} else if (value instanceof String[]) {
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import com.vaadin.Application;
import com.vaadin.external.json.JSONArray;
registerType(String.class, JsonEncoder.VTYPE_STRING);
registerType(Connector.class, JsonEncoder.VTYPE_CONNECTOR);
registerType(Boolean.class, JsonEncoder.VTYPE_BOOLEAN);
+ registerType(boolean.class, JsonEncoder.VTYPE_BOOLEAN);
registerType(Integer.class, JsonEncoder.VTYPE_INTEGER);
+ registerType(int.class, JsonEncoder.VTYPE_INTEGER);
registerType(Float.class, JsonEncoder.VTYPE_FLOAT);
+ registerType(float.class, JsonEncoder.VTYPE_FLOAT);
registerType(Double.class, JsonEncoder.VTYPE_DOUBLE);
+ registerType(double.class, JsonEncoder.VTYPE_FLOAT);
registerType(Long.class, JsonEncoder.VTYPE_LONG);
+ 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);
registerType(List.class, JsonEncoder.VTYPE_LIST);
+ registerType(Set.class, JsonEncoder.VTYPE_SET);
}
private static void registerType(Class<?> type, String transportType) {
val = decodeArray((JSONArray) value, application);
} else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
val = decodeList((JSONArray) value, application);
+ } else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
+ val = decodeSet((JSONArray) value, application);
} else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
val = decodeMap((JSONObject) value, application);
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
return list.toArray(new Object[list.size()]);
}
- private static List decodeList(JSONArray jsonArray, Application application)
- throws JSONException {
+ private static List<Object> decodeList(JSONArray jsonArray,
+ Application application) throws JSONException {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < jsonArray.length(); ++i) {
// each entry always has two elements: type and value
return list;
}
+ private static Set<Object> decodeSet(JSONArray jsonArray,
+ Application application) throws JSONException {
+ HashSet<Object> set = new HashSet<Object>();
+ set.addAll(decodeList(jsonArray, application));
+ return set;
+ }
+
/**
* Encode a value to a JSON representation for transport from the server to
* the client.
if (null == value) {
return combineTypeAndValue(JsonEncoder.VTYPE_NULL, JSONObject.NULL);
- } else if (value instanceof String[]) {
+ }
+
+ if (valueType == null) {
+ valueType = value.getClass();
+ }
+
+ String transportType = getTransportType(valueType);
+ if (value instanceof String[]) {
String[] array = (String[]) value;
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < array.length; ++i) {
} else if (value instanceof Boolean) {
return combineTypeAndValue(JsonEncoder.VTYPE_BOOLEAN, value);
} else if (value instanceof Number) {
- return combineTypeAndValue(getTransportType(value), value);
- } else if (value instanceof List) {
- List list = (List) value;
- JSONArray jsonArray = encodeList(list, application);
- return combineTypeAndValue(JsonEncoder.VTYPE_LIST, jsonArray);
+ return combineTypeAndValue(transportType, value);
+ } else if (value instanceof Collection) {
+ if (transportType == null) {
+ throw new RuntimeException(
+ "Unable to serialize unsupported type: " + valueType);
+ }
+ Collection<?> collection = (Collection<?>) value;
+ JSONArray jsonArray = encodeCollection(collection, application);
+
+ return combineTypeAndValue(transportType, jsonArray);
} else if (value instanceof Object[]) {
Object[] array = (Object[]) value;
JSONArray jsonArray = encodeArrayContents(array, application);
Connector connector = (Connector) value;
return combineTypeAndValue(JsonEncoder.VTYPE_CONNECTOR,
connector.getConnectorId());
- } else if (getTransportType(value) != null) {
- return combineTypeAndValue(getTransportType(value),
- String.valueOf(value));
+ } else if (transportType != null) {
+ return combineTypeAndValue(transportType, String.valueOf(value));
} else {
// Any object that we do not know how to encode we encode by looping
// through fields
- if (valueType == null) {
- valueType = value.getClass();
- }
-
return combineTypeAndValue(valueType.getCanonicalName(),
encodeObject(value, application));
}
return jsonArray;
}
- private static JSONArray encodeList(List list, Application application)
- throws JSONException {
+ private static JSONArray encodeCollection(Collection collection,
+ Application application) throws JSONException {
JSONArray jsonArray = new JSONArray();
- for (Object o : list) {
+ for (Object o : collection) {
// TODO handle object graph loops?
jsonArray.put(encode(o, application));
}
}
private static JSONArray combineTypeAndValue(String type, Object value) {
+ if (type == null) {
+ throw new RuntimeException("Type for value " + value
+ + " cannot be null!");
+ }
JSONArray outerArray = new JSONArray();
outerArray.put(type);
outerArray.put(value);
* @return
* @throws JSONException
*/
- private static String getTransportType(Object value) throws JSONException {
+ private static String getTransportType(Object value) {
if (null == value) {
return JsonEncoder.VTYPE_NULL;
}
- String transportType = typeToTransportType.get(value.getClass());
- return transportType;
+ return getTransportType(value.getClass());
+ }
+
+ /**
+ * Gets the transport type for the given class. Returns null if no transport
+ * type can be found.
+ *
+ * @param valueType
+ * The type that should be transported
+ * @return
+ * @throws JSONException
+ */
+ private static String getTransportType(Class<?> valueType) {
+ return typeToTransportType.get(valueType);
+
}
}