]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add DiffJSONSerializer for updating existing objects (#8879)
authorLeif Åstrand <leif@vaadin.com>
Thu, 31 May 2012 20:12:57 +0000 (23:12 +0300)
committerLeif Åstrand <leif@vaadin.com>
Wed, 6 Jun 2012 10:33:44 +0000 (13:33 +0300)
This is work in progress towards using declared types for data received
from the server.

src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/communication/DiffJSONSerializer.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java

index 530fd546dba84685185d9b2c6da2abcf8366ff13..c7ec5236b019c30500af416de463ad2d19ee524f 100644 (file)
@@ -1412,7 +1412,7 @@ public class ApplicationConnection {
                                     states.getJavaScriptObject(connectorId));
 
                             JsonDecoder.decodeValue(stateDataAndType,
-                                    connector.getState(), connectorMap,
+                                    connector.getState(),
                                     ApplicationConnection.this);
 
                             StateChangeEvent event = GWT
@@ -1578,8 +1578,7 @@ public class ApplicationConnection {
         Object[] parameters = new Object[parametersJson.size()];
         for (int j = 0; j < parametersJson.size(); ++j) {
             parameters[j] = JsonDecoder.decodeValue(
-                    (JSONArray) parametersJson.get(j), null, getConnectorMap(),
-                    this);
+                    (JSONArray) parametersJson.get(j), null, this);
         }
         return new MethodInvocation(connectorId, interfaceName, methodName,
                 parameters);
diff --git a/src/com/vaadin/terminal/gwt/client/communication/DiffJSONSerializer.java b/src/com/vaadin/terminal/gwt/client/communication/DiffJSONSerializer.java
new file mode 100644 (file)
index 0000000..29cb714
--- /dev/null
@@ -0,0 +1,19 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.client.communication;
+
+import com.google.gwt.json.client.JSONValue;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+
+public interface DiffJSONSerializer<T> extends JSONSerializer<T> {
+    /**
+     * Update the target object in place based on the passed JSON data.
+     * 
+     * @param target
+     * @param jsonValue
+     * @param connection
+     */
+    public void update(T target, Type type, JSONValue jsonValue,
+            ApplicationConnection connection);
+}
index f7b3df6b05951ff4a35cf7d70d6e032f52007afe..fe879b2fa77f23648fafc2fba7e794ec687bdcf3 100644 (file)
@@ -34,14 +34,9 @@ public interface JSONSerializer<T> {
      * 
      * @param jsonValue
      *            JSON map from property name to property value
-     * @param target
-     *            The object to write the deserialized values to
-     * @param idMapper
-     *            mapper from paintable id to paintable, used to decode
-     *            references to paintables
      * @return A deserialized object
      */
-    T deserialize(JSONValue jsonValue, T target, ConnectorMap idMapper,
+    T deserialize(Type type, JSONValue jsonValue,
             ApplicationConnection connection);
 
     /**
index 8df92a141eee0776f2b595ca340120d1afb4291a..8d22481783d67dc3eb49107d1969ddda6b3cbde6 100644 (file)
@@ -49,26 +49,25 @@ public class JsonDecoder {
      * @return decoded value (does not contain JSON types)
      */
     public static Object decodeValue(JSONArray jsonArray, Object target,
-            ConnectorMap idMapper, ApplicationConnection connection) {
+            ApplicationConnection connection) {
         String type = ((JSONString) jsonArray.get(0)).stringValue();
-        return decodeValue(type, jsonArray.get(1), target, idMapper, connection);
+        return decodeValue(type, jsonArray.get(1), target, connection);
     }
 
     private static Object decodeValue(String variableType, JSONValue value,
-            Object target, ConnectorMap idMapper,
-            ApplicationConnection connection) {
+            Object target, ApplicationConnection connection) {
         Object val = null;
         // TODO type checks etc.
         if (JsonEncoder.VTYPE_NULL.equals(variableType)) {
             val = null;
         } else if (JsonEncoder.VTYPE_ARRAY.equals(variableType)) {
-            val = decodeArray((JSONArray) value, idMapper, connection);
+            val = decodeArray((JSONArray) value, connection);
         } else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
-            val = decodeMap((JSONObject) value, idMapper, connection);
+            val = decodeMap((JSONObject) value, connection);
         } else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
-            val = decodeList((JSONArray) value, idMapper, connection);
+            val = decodeList((JSONArray) value, connection);
         } else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
-            val = decodeSet((JSONArray) value, idMapper, connection);
+            val = decodeSet((JSONArray) value, connection);
         } else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
             val = decodeStringArray((JSONArray) value);
         } else if (JsonEncoder.VTYPE_STRING.equals(variableType)) {
@@ -89,39 +88,44 @@ public class JsonDecoder {
             // TODO handle properly
             val = Boolean.valueOf(String.valueOf(value));
         } else if (JsonEncoder.VTYPE_CONNECTOR.equals(variableType)) {
-            val = idMapper.getConnector(((JSONString) value).stringValue());
+            val = ConnectorMap.get(connection).getConnector(
+                    ((JSONString) value).stringValue());
         } else {
-            return decodeObject(variableType, value, target, idMapper,
+            return decodeObject(new Type(variableType, null), value, target,
                     connection);
         }
 
         return val;
     }
 
-    private static Object decodeObject(String variableType,
-            JSONValue encodedValue, Object target, ConnectorMap idMapper,
-            ApplicationConnection connection) {
+    private static Object decodeObject(Type type, JSONValue encodedValue,
+            Object target, ApplicationConnection connection) {
         // object, class name as type
         JSONSerializer<Object> serializer = connection.getSerializerMap()
-                .getSerializer(variableType);
+                .getSerializer(type.getBaseTypeName());
         // TODO handle case with no serializer found
-        Object object = serializer.deserialize(encodedValue, target, idMapper,
-                connection);
-        return object;
+
+        if (target != null && serializer instanceof DiffJSONSerializer<?>) {
+            DiffJSONSerializer<Object> diffSerializer = (DiffJSONSerializer<Object>) serializer;
+            diffSerializer.update(target, type, encodedValue, connection);
+            return target;
+        } else {
+            Object object = serializer.deserialize(type, encodedValue,
+                    connection);
+            return object;
+        }
     }
 
     private static Map<Object, Object> decodeMap(JSONObject jsonMap,
-            ConnectorMap idMapper, ApplicationConnection connection) {
+            ApplicationConnection connection) {
         HashMap<Object, Object> map = new HashMap<Object, Object>();
         Iterator<String> it = jsonMap.keySet().iterator();
         while (it.hasNext()) {
             String key = it.next();
             JSONArray encodedKey = (JSONArray) JSONParser.parseStrict(key);
             JSONArray encodedValue = (JSONArray) jsonMap.get(key);
-            Object decodedKey = decodeValue(encodedKey, null, idMapper,
-                    connection);
-            Object decodedValue = decodeValue(encodedValue, null, idMapper,
-                    connection);
+            Object decodedKey = decodeValue(encodedKey, null, connection);
+            Object decodedValue = decodeValue(encodedValue, null, connection);
             map.put(decodedKey, decodedValue);
         }
         return map;
@@ -137,32 +141,31 @@ public class JsonDecoder {
     }
 
     private static Object[] decodeArray(JSONArray jsonArray,
-            ConnectorMap idMapper, ApplicationConnection connection) {
-        List<Object> list = decodeList(jsonArray, idMapper, connection);
+            ApplicationConnection connection) {
+        List<Object> list = decodeList(jsonArray, connection);
         return list.toArray(new Object[list.size()]);
     }
 
     private static List<Object> decodeList(JSONArray jsonArray,
-            ConnectorMap idMapper, ApplicationConnection connection) {
+            ApplicationConnection connection) {
         List<Object> tokens = new ArrayList<Object>();
-        decodeIntoCollection(jsonArray, idMapper, connection, tokens);
+        decodeIntoCollection(jsonArray, connection, tokens);
         return tokens;
     }
 
     private static Set<Object> decodeSet(JSONArray jsonArray,
-            ConnectorMap idMapper, ApplicationConnection connection) {
+            ApplicationConnection connection) {
         Set<Object> tokens = new HashSet<Object>();
-        decodeIntoCollection(jsonArray, idMapper, connection, tokens);
+        decodeIntoCollection(jsonArray, connection, tokens);
         return tokens;
     }
 
     private static void decodeIntoCollection(JSONArray jsonArray,
-            ConnectorMap idMapper, ApplicationConnection connection,
-            Collection<Object> tokens) {
+            ApplicationConnection connection, Collection<Object> tokens) {
         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, null, idMapper, connection));
+            tokens.add(decodeValue(entryArray, null, connection));
         }
     }
 }
index 2ee7df7f6dc0c15d15b905db4534ee538f6a1e62..1ae8cc4755ea09bf17629ee9f1d624e76ec97222 100644 (file)
@@ -12,14 +12,14 @@ import com.vaadin.terminal.gwt.client.ConnectorMap;
 
 public class URLReference_Serializer implements JSONSerializer<URLReference> {
 
-    public URLReference deserialize(JSONValue jsonValue, URLReference target,
-            ConnectorMap idMapper, ApplicationConnection connection) {
+    public URLReference deserialize(Type type, JSONValue jsonValue,
+            ApplicationConnection connection) {
         URLReference reference = GWT.create(URLReference.class);
         JSONObject json = (JSONObject) jsonValue;
         if (json.containsKey("URL")) {
             JSONArray jsonURL = (JSONArray) json.get("URL");
             String URL = (String) JsonDecoder.decodeValue(jsonURL, null,
-                    idMapper, connection);
+                    connection);
             reference.setURL(connection.translateVaadinUri(URL));
         }
         return reference;
index bc031f4bdb6b19db2ba228b76049a671fa3363a2..6aa6b073ee0122b6ac00b74df9b6c0942d7a2692 100644 (file)
@@ -30,6 +30,7 @@ import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
+import com.vaadin.terminal.gwt.client.communication.DiffJSONSerializer;
 import com.vaadin.terminal.gwt.client.communication.JSONSerializer;
 import com.vaadin.terminal.gwt.client.communication.JsonDecoder;
 import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
@@ -107,13 +108,20 @@ public class SerializerGenerator extends Generator {
                 serializerClassName);
         composer.addImport(GWT.class.getName());
         composer.addImport(JSONArray.class.getName());
+        composer.addImport(com.vaadin.terminal.gwt.client.communication.Type.class
+                .getName());
         // composer.addImport(JSONObject.class.getName());
         // composer.addImport(VPaintableMap.class.getName());
         composer.addImport(JsonDecoder.class.getName());
         // composer.addImport(VaadinSerializer.class.getName());
 
-        composer.addImplementedInterface(JSONSerializer.class.getName() + "<"
-                + beanQualifiedSourceName + ">");
+        if (isEnum) {
+            composer.addImplementedInterface(JSONSerializer.class.getName()
+                    + "<" + beanQualifiedSourceName + ">");
+        } else {
+            composer.addImplementedInterface(DiffJSONSerializer.class.getName()
+                    + "<" + beanQualifiedSourceName + ">");
+        }
 
         SourceWriter sourceWriter = composer.createSourceWriter(context,
                 printWriter);
@@ -138,20 +146,39 @@ public class SerializerGenerator extends Generator {
             writeBeanSerializer(logger, sourceWriter, beanType);
         }
         // }
+        sourceWriter.outdent();
         sourceWriter.println("}");
+        sourceWriter.println();
+
+        // Updater
+        // public void update(T target, Type type, JSONValue jsonValue,
+        // ApplicationConnection connection);
+        if (!isEnum) {
+            sourceWriter.println("public void update("
+                    + beanQualifiedSourceName + " target, Type type, "
+                    + JSONValue.class.getName() + " jsonValue, "
+                    + ApplicationConnection.class.getName() + " connection) {");
+            sourceWriter.indent();
+
+            writeBeanDeserializer(logger, sourceWriter, beanType, true);
+
+            sourceWriter.outdent();
+            sourceWriter.println("}");
+        }
 
         // Deserializer
+        // T deserialize(Type type, JSONValue jsonValue, ApplicationConnection
+        // connection);
         sourceWriter.println("public " + beanQualifiedSourceName
-                + " deserialize(" + JSONValue.class.getName() + " jsonValue, "
-                + beanQualifiedSourceName + " target, "
-                + ConnectorMap.class.getName() + " idMapper, "
-                + ApplicationConnection.class.getName() + " connection) {");
+                + " deserialize(Type type, " + JSONValue.class.getName()
+                + " jsonValue, " + ApplicationConnection.class.getName()
+                + " connection) {");
         sourceWriter.indent();
 
         if (isEnum) {
             writeEnumDeserializer(logger, sourceWriter, beanType.isEnum());
         } else {
-            writeBeanDeserializer(logger, sourceWriter, beanType);
+            writeBeanDeserializer(logger, sourceWriter, beanType, false);
         }
         sourceWriter.println("}");
         sourceWriter.outdent();
@@ -183,18 +210,14 @@ public class SerializerGenerator extends Generator {
     }
 
     private void writeBeanDeserializer(TreeLogger logger,
-            SourceWriter sourceWriter, JClassType beanType) {
+            SourceWriter sourceWriter, JClassType beanType, boolean update) {
         String beanQualifiedSourceName = beanType.getQualifiedSourceName();
 
-        // if (target == null) {
-        sourceWriter.println("if (target == null) {");
-        sourceWriter.indent();
-
-        // target = GWT.create(VButtonState.class);
-        sourceWriter.println("target = GWT.create(" + beanQualifiedSourceName
-                + ".class);");
-        sourceWriter.outdent();
-        sourceWriter.println("}");
+        if (!update) {
+            sourceWriter.println(beanQualifiedSourceName
+                    + " target = GWT.create(" + beanQualifiedSourceName
+                    + ".class);");
+        }
 
         // JSONOBject json = (JSONObject)jsonValue;
         sourceWriter.println(JSONObject.class.getName() + " json = ("
@@ -230,37 +253,26 @@ public class SerializerGenerator extends Generator {
                 fieldType = setterParameterType.getQualifiedSourceName();
             }
 
-            // String referenceValue;
-            sourceWriter.println(fieldType + " referenceValue;");
-            // if (target == null) {
-            sourceWriter.println("if (target == null) {");
-            sourceWriter.indent();
-            // referenceValue = null;
-            sourceWriter.println("referenceValue = null;");
-            // } else {
-            sourceWriter.println("} else {");
-            // referenceValue = target.getHeight();
-            sourceWriter.println("referenceValue = target." + getterName
-                    + "();");
-            // }
-            sourceWriter.outdent();
-            sourceWriter.println("}");
+            // String referenceValue = target.getHeight();
+            sourceWriter.println(fieldType + " referenceValue = target."
+                    + getterName + "();");
 
             // target.setHeight((String)
             // JsonDecoder.decodeValue(jsonFieldValue,referenceValue, idMapper,
             // connection));
             sourceWriter.println("target." + setterName + "((" + fieldType
                     + ") " + JsonDecoder.class.getName() + ".decodeValue("
-                    + jsonFieldName
-                    + ", referenceValue, idMapper, connection));");
+                    + jsonFieldName + ", referenceValue, connection));");
 
             // } ... end of if contains
             sourceWriter.println("}");
             sourceWriter.outdent();
         }
 
-        // return target;
-        sourceWriter.println("return target;");
+        if (!update) {
+            // return target;
+            sourceWriter.println("return target;");
+        }
 
     }