aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-03-19 15:46:24 +0200
committerArtur Signell <artur@vaadin.com>2012-03-21 15:27:46 +0200
commitcf925d995b0ba618eaba14c6213f2bdad4efcb8a (patch)
treeb9a0f91048ad82db261a50e49976be40cf5d70a8 /src
parent9a5dbba61009caf7d011a1b9d024a9806bdb50c2 (diff)
downloadvaadin-framework-cf925d995b0ba618eaba14c6213f2bdad4efcb8a.tar.gz
vaadin-framework-cf925d995b0ba618eaba14c6213f2bdad4efcb8a.zip
#8515 Additional fix for sets, and lists from client to server
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java15
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java45
-rw-r--r--src/com/vaadin/terminal/gwt/server/JsonCodec.java84
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java5
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java14
5 files changed, 132 insertions, 31 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java b/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
index 4bc9431d49..86a64cb47c 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
@@ -6,9 +6,11 @@ package com.vaadin.terminal.gwt.client.communication;
import java.util.ArrayList;
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.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray;
@@ -63,6 +65,8 @@ public class JsonDecoder {
val = decodeMap((JSONObject) value, idMapper, connection);
} else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
val = decodeList((JSONArray) value, idMapper, connection);
+ } else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
+ val = decodeSet((JSONArray) value, idMapper, connection);
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
val = decodeStringArray((JSONArray) value);
} else if (JsonEncoder.VTYPE_STRING.equals(variableType)) {
@@ -135,4 +139,15 @@ public class JsonDecoder {
}
return tokens;
}
+
+ private static Set<Object> decodeSet(JSONArray jsonArray,
+ ConnectorMap idMapper, ApplicationConnection connection) {
+ Set<Object> tokens = new HashSet<Object>();
+ for (int i = 0; i < jsonArray.size(); ++i) {
+ // each entry always has two elements: type and value
+ JSONArray entryArray = (JSONArray) jsonArray.get(i);
+ tokens.add(decodeValue(entryArray, idMapper, connection));
+ }
+ return tokens;
+ }
}
diff --git a/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java b/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
index cc8b36dfa4..1215743790 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
@@ -4,8 +4,10 @@
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;
@@ -41,6 +43,7 @@ public class JsonEncoder {
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";
/**
@@ -72,13 +75,7 @@ public class JsonEncoder {
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();
@@ -92,6 +89,9 @@ public class JsonEncoder {
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) {
@@ -111,6 +111,35 @@ public class JsonEncoder {
}
}
+ 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));
@@ -137,6 +166,8 @@ public class JsonEncoder {
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[]) {
diff --git a/src/com/vaadin/terminal/gwt/server/JsonCodec.java b/src/com/vaadin/terminal/gwt/server/JsonCodec.java
index 9fea64a1c7..402d219a70 100644
--- a/src/com/vaadin/terminal/gwt/server/JsonCodec.java
+++ b/src/com/vaadin/terminal/gwt/server/JsonCodec.java
@@ -11,10 +11,13 @@ import java.io.Serializable;
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;
@@ -38,16 +41,22 @@ public class JsonCodec implements Serializable {
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) {
@@ -80,6 +89,8 @@ public class JsonCodec implements Serializable {
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)) {
@@ -141,8 +152,8 @@ public class JsonCodec implements Serializable {
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
@@ -152,6 +163,13 @@ public class JsonCodec implements Serializable {
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.
@@ -174,7 +192,14 @@ public class JsonCodec implements Serializable {
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) {
@@ -186,11 +211,16 @@ public class JsonCodec implements Serializable {
} 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);
@@ -203,16 +233,11 @@ public class JsonCodec implements Serializable {
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));
}
@@ -290,10 +315,10 @@ public class JsonCodec implements Serializable {
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));
}
@@ -312,6 +337,10 @@ public class JsonCodec implements Serializable {
}
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);
@@ -326,12 +355,25 @@ public class JsonCodec implements Serializable {
* @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);
+
}
}
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
index bb05432964..0fe5a38096 100644
--- a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
@@ -230,8 +230,9 @@ public class SerializerGenerator extends Generator {
List<JMethod> setterMethods = new ArrayList<JMethod>();
- while (!beanType.getQualifiedSourceName()
- .equals(Object.class.getName())) {
+ while (beanType != null
+ && !beanType.getQualifiedSourceName().equals(
+ Object.class.getName())) {
for (JMethod method : beanType.getMethods()) {
// Process all setters that have corresponding fields
if (!method.isPublic() || method.isStatic()
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java
index 52b599253f..420c3ae6e7 100644
--- a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java
@@ -7,6 +7,7 @@ package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -199,7 +200,16 @@ public class SerializerMapGenerator extends Generator {
continue;
}
for (JType type : method.getParameterTypes()) {
- types.add(type.isClass());
+ JClassType t = type.isClass();
+ JClassType interfaceType = type.isInterface();
+ if (t != null) {
+ types.add(t);
+ } else if (interfaceType != null) {
+ types.add(interfaceType);
+ } else {
+ System.err.println("Unknown method parameter type: "
+ + type.getQualifiedSourceName());
+ }
}
}
}
@@ -242,6 +252,8 @@ public class SerializerMapGenerator extends Generator {
frameworkHandledTypes.add(String[].class);
frameworkHandledTypes.add(Object[].class);
frameworkHandledTypes.add(Map.class);
+ frameworkHandledTypes.add(List.class);
+ frameworkHandledTypes.add(Set.class);
}