]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8515 Added serialization support for Lists containing supported types.
authorArtur Signell <artur@vaadin.com>
Fri, 9 Mar 2012 14:10:21 +0000 (16:10 +0200)
committerArtur Signell <artur@vaadin.com>
Tue, 13 Mar 2012 16:10:44 +0000 (18:10 +0200)
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
src/com/vaadin/terminal/gwt/server/JsonCodec.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java

index c889a65ce53555c6a9063daf26ea5047f813fe1f..f956f56f92456eeb88e498fa1557ffeab2fe5026 100644 (file)
@@ -1196,7 +1196,7 @@ public class ApplicationConnection {
                             JSONArray stateDataAndType = new JSONArray(
                                     states.getJavaScriptObject(connectorId));
 
-                            Object state = JsonDecoder.convertValue(
+                            Object state = JsonDecoder.decodeValue(
                                     stateDataAndType, connectorMap,
                                     ApplicationConnection.this);
 
@@ -1317,7 +1317,7 @@ public class ApplicationConnection {
         JSONArray parametersJson = (JSONArray) rpcCall.get(3);
         Object[] parameters = new Object[parametersJson.size()];
         for (int j = 0; j < parametersJson.size(); ++j) {
-            parameters[j] = JsonDecoder.convertValue(
+            parameters[j] = JsonDecoder.decodeValue(
                     (JSONArray) parametersJson.get(j), getConnectorMap(), this);
         }
         return new MethodInvocation(connectorId, interfaceName, methodName,
index 2250bbbb8dc4a464fec3f3e4d022ba9120ee8d50..5fbb801e87ae2bf2a6898d8c583b951156259c9f 100644 (file)
@@ -19,7 +19,7 @@ import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
 
 /**
- * Client side decoder for converting shared state and other values from JSON
+ * Client side decoder for decodeing shared state and other values from JSON
  * received from the server.
  * 
  * Currently, basic data types as well as Map, String[] and Object[] are
@@ -33,8 +33,8 @@ public class JsonDecoder {
     static SerializerMap serializerMap = GWT.create(SerializerMap.class);
 
     /**
-     * Convert a JSON array with two elements (type and value) into a
-     * client-side type, recursively if necessary.
+     * Decode a JSON array with two elements (type and value) into a client-side
+     * type, recursively if necessary.
      * 
      * @param jsonArray
      *            JSON array with two elements
@@ -42,26 +42,28 @@ public class JsonDecoder {
      *            mapper between connector ID and {@link Connector} objects
      * @param connection
      *            reference to the current ApplicationConnection
-     * @return converted value (does not contain JSON types)
+     * @return decoded value (does not contain JSON types)
      */
-    public static Object convertValue(JSONArray jsonArray,
+    public static Object decodeValue(JSONArray jsonArray,
             ConnectorMap idMapper, ApplicationConnection connection) {
         String type = ((JSONString) jsonArray.get(0)).stringValue();
-        return convertValue(type, jsonArray.get(1), idMapper, connection);
+        return decodeValue(type, jsonArray.get(1), idMapper, connection);
     }
 
-    private static Object convertValue(String variableType, Object value,
+    private static Object decodeValue(String variableType, Object value,
             ConnectorMap idMapper, ApplicationConnection connection) {
         Object val = null;
         // TODO type checks etc.
         if (JsonEncoder.VTYPE_UNDEFINED.equals(variableType)) {
             val = null;
         } else if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) {
-            val = convertArray((JSONArray) value, idMapper, connection);
+            val = decodeArray((JSONArray) value, idMapper, connection);
         } else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
-            val = convertMap((JSONObject) value, idMapper, connection);
+            val = decodeMap((JSONObject) value, idMapper, connection);
+        } else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
+            val = decodeList((JSONArray) value, idMapper, connection);
         } else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
-            val = convertStringArray((JSONArray) value);
+            val = decodeStringArray((JSONArray) value);
         } else if (JsonEncoder.VTYPE_STRING.equals(variableType)) {
             val = ((JSONString) value).stringValue();
         } else if (JsonEncoder.VTYPE_INTEGER.equals(variableType)) {
@@ -95,20 +97,20 @@ public class JsonDecoder {
         return val;
     }
 
-    private static Map<String, Object> convertMap(JSONObject jsonMap,
+    private static Map<String, Object> decodeMap(JSONObject jsonMap,
             ConnectorMap idMapper, ApplicationConnection connection) {
         HashMap<String, Object> map = new HashMap<String, Object>();
         Iterator<String> it = jsonMap.keySet().iterator();
         while (it.hasNext()) {
             String key = it.next();
             map.put(key,
-                    convertValue((JSONArray) jsonMap.get(key), idMapper,
+                    decodeValue((JSONArray) jsonMap.get(key), idMapper,
                             connection));
         }
         return map;
     }
 
-    private static String[] convertStringArray(JSONArray jsonArray) {
+    private static String[] decodeStringArray(JSONArray jsonArray) {
         int size = jsonArray.size();
         List<String> tokens = new ArrayList<String>(size);
         for (int i = 0; i < size; ++i) {
@@ -117,15 +119,20 @@ public class JsonDecoder {
         return tokens.toArray(new String[tokens.size()]);
     }
 
-    private static Object[] convertArray(JSONArray jsonArray,
+    private static Object[] decodeArray(JSONArray jsonArray,
+            ConnectorMap idMapper, ApplicationConnection connection) {
+        List<Object> list = decodeList(jsonArray, idMapper, connection);
+        return list.toArray(new Object[list.size()]);
+    }
+
+    private static List<Object> decodeList(JSONArray jsonArray,
             ConnectorMap idMapper, ApplicationConnection connection) {
         List<Object> tokens = new ArrayList<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(convertValue(entryArray, idMapper, connection));
+            tokens.add(decodeValue(entryArray, idMapper, connection));
         }
-        return tokens.toArray(new Object[tokens.size()]);
+        return tokens;
     }
-
 }
index c7d49875d7f82128497add9a1da3892673106c78..874313ba02d71adb2fb7881fb1fcb5bcae19ff34 100644 (file)
@@ -4,6 +4,7 @@
 
 package com.vaadin.terminal.gwt.client.communication;
 
+import java.util.List;
 import java.util.Map;
 
 import com.google.gwt.json.client.JSONArray;
@@ -39,8 +40,7 @@ public class JsonEncoder {
     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
-    public static final String VTYPE_SHAREDSTATE = "t";
+    public static final String VTYPE_LIST = "L";
 
     // TODO is this needed?
     public static final String VTYPE_UNDEFINED = "u";
@@ -135,6 +135,8 @@ public class JsonEncoder {
             return VTYPE_DOUBLE;
         } else if (value instanceof Long) {
             return VTYPE_LONG;
+        } else if (value instanceof List) {
+            return VTYPE_LIST;
         } else if (value instanceof Enum) {
             return VTYPE_STRING; // transported as string representation
         } else if (value instanceof String[]) {
index 24053d2c15f84bbaada2ad180cc4e5fe6149face..034d283740e31675d2e330f3b15146e375310908 100644 (file)
@@ -12,7 +12,7 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> {
             ConnectorMap idMapper, ApplicationConnection connection) {
         URLReference reference = GWT.create(URLReference.class);
         JSONArray jsonURL = (JSONArray) jsonValue.get("URL");
-        String URL = (String) JsonDecoder.convertValue(jsonURL, idMapper,
+        String URL = (String) JsonDecoder.decodeValue(jsonURL, idMapper,
                 connection);
         reference.setURL(connection.translateVaadinUri(URL));
         return reference;
index 0a617470a538b3d52d7daff64df4e644859803bc..4b3f41508e3ee4c9f1632c2dc407657d4a384d31 100644 (file)
@@ -45,6 +45,7 @@ public class JsonCodec implements Serializable {
         registerType(String[].class, JsonEncoder.VTYPE_STRINGARRAY);
         registerType(Object[].class, JsonEncoder.VTYPE_ARRAY);
         registerType(Map.class, JsonEncoder.VTYPE_MAP);
+        registerType(List.class, JsonEncoder.VTYPE_LIST);
     }
 
     private static void registerType(Class<?> type, String transportType) {
@@ -65,19 +66,21 @@ public class JsonCodec implements Serializable {
      */
     public static Object decode(JSONArray value, PaintableIdMapper idMapper)
             throws JSONException {
-        return convertVariableValue(value.getString(0), value.get(1), idMapper);
+        return decodeVariableValue(value.getString(0), value.get(1), idMapper);
     }
 
-    private static Object convertVariableValue(String variableType,
+    private static Object decodeVariableValue(String variableType,
             Object value, PaintableIdMapper idMapper) throws JSONException {
         Object val = null;
         // TODO type checks etc.
         if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) {
-            val = convertArray((JSONArray) value, idMapper);
+            val = decodeArray((JSONArray) value, idMapper);
+        } else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
+            val = decodeList((JSONArray) value, idMapper);
         } else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
-            val = convertMap((JSONObject) value, idMapper);
+            val = decodeMap((JSONObject) value, idMapper);
         } else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
-            val = convertStringArray((JSONArray) value);
+            val = decodeStringArray((JSONArray) value);
         } else if (JsonEncoder.VTYPE_STRING.equals(variableType)) {
             val = value;
         } else if (JsonEncoder.VTYPE_INTEGER.equals(variableType)) {
@@ -107,7 +110,7 @@ public class JsonCodec implements Serializable {
         return val;
     }
 
-    private static Object convertMap(JSONObject jsonMap,
+    private static Object decodeMap(JSONObject jsonMap,
             PaintableIdMapper idMapper) throws JSONException {
         HashMap<String, Object> map = new HashMap<String, Object>();
         Iterator<String> it = jsonMap.keys();
@@ -118,7 +121,7 @@ public class JsonCodec implements Serializable {
         return map;
     }
 
-    private static String[] convertStringArray(JSONArray jsonArray)
+    private static String[] decodeStringArray(JSONArray jsonArray)
             throws JSONException {
         int length = jsonArray.length();
         List<String> tokens = new ArrayList<String>(length);
@@ -128,15 +131,21 @@ public class JsonCodec implements Serializable {
         return tokens.toArray(new String[tokens.size()]);
     }
 
-    private static Object convertArray(JSONArray jsonArray,
+    private static Object decodeArray(JSONArray jsonArray,
             PaintableIdMapper idMapper) throws JSONException {
-        List<Object> tokens = new ArrayList<Object>();
+        List list = decodeList(jsonArray, idMapper);
+        return list.toArray(new Object[list.size()]);
+    }
+
+    private static List decodeList(JSONArray jsonArray,
+            PaintableIdMapper idMapper) 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
             JSONArray entryArray = jsonArray.getJSONArray(i);
-            tokens.add(decode(entryArray, idMapper));
+            list.add(decode(entryArray, idMapper));
         }
-        return tokens.toArray(new Object[tokens.size()]);
+        return list;
     }
 
     /**
@@ -176,6 +185,10 @@ public class JsonCodec implements Serializable {
             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, idMapper);
+            return combineTypeAndValue(JsonEncoder.VTYPE_LIST, jsonArray);
         } else if (value instanceof Object[]) {
             Object[] array = (Object[]) value;
             JSONArray jsonArray = encodeArrayContents(array, idMapper);
@@ -267,9 +280,19 @@ public class JsonCodec implements Serializable {
     private static JSONArray encodeArrayContents(Object[] array,
             PaintableIdMapper idMapper) throws JSONException {
         JSONArray jsonArray = new JSONArray();
-        for (int i = 0; i < array.length; ++i) {
+        for (Object o : array) {
+            // TODO handle object graph loops?
+            jsonArray.put(encode(o, idMapper));
+        }
+        return jsonArray;
+    }
+
+    private static JSONArray encodeList(List list, PaintableIdMapper idMapper)
+            throws JSONException {
+        JSONArray jsonArray = new JSONArray();
+        for (Object o : list) {
             // TODO handle object graph loops?
-            jsonArray.put(encode(array[i], idMapper));
+            jsonArray.put(encode(o, idMapper));
         }
         return jsonArray;
     }
index f80b7a3f27ebf153e688f174cf5b10949ef90754..bb0543296494340e62e49b7e7ca365ca6c0f2e79 100644 (file)
@@ -175,7 +175,7 @@ public class SerializerGenerator extends Generator {
                     + " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");
 
             // state.setHeight((String)
-            // JsonDecoder.convertValue(jsonFieldValue,idMapper, connection));
+            // JsonDecoder.decodeValue(jsonFieldValue,idMapper, connection));
 
             String fieldType;
             JPrimitiveType primitiveType = setterParameterType.isPrimitive();
@@ -187,8 +187,8 @@ public class SerializerGenerator extends Generator {
             }
 
             sourceWriter.println("state." + setterName + "((" + fieldType
-                    + ") JsonDecoder.convertValue(" + jsonFieldName
-                    + ", idMapper, connection));");
+                    + ") " + JsonDecoder.class.getName() + ".decodeValue("
+                    + jsonFieldName + ", idMapper, connection));");
         }
 
         // return state;
index c2a54030f785a9f81fd118976f58b7cc9235cb8d..52b599253f8c843c04b78621035f53bcd786f0ed 100644 (file)
@@ -219,8 +219,14 @@ public class SerializerMapGenerator extends Generator {
                 continue;
             }
 
-            serializableTypes.add(setterType.isClass());
-            findSubTypesNeedingSerializers(type, serializableTypes);
+            JClassType setterTypeClass = setterType.isClass();
+            if (setterTypeClass != null) {
+                // setterTypeClass is null at least for List<String>. It is
+                // possible that we need to handle the cases somehow, for
+                // instance for List<MyObject>.
+                serializableTypes.add(setterTypeClass);
+                findSubTypesNeedingSerializers(type, serializableTypes);
+            }
         }
     }