summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-05-31 23:12:57 +0300
committerLeif Åstrand <leif@vaadin.com>2012-06-06 13:33:44 +0300
commit694a588f94785431d012daa8d001f2f931aec852 (patch)
treed6ca1de26a71e2e176ebf600be305e989b9080ed /src
parentdc7e238f2dc9ec6c9faad5ab6dcfdab8f2eaae46 (diff)
downloadvaadin-framework-694a588f94785431d012daa8d001f2f931aec852.tar.gz
vaadin-framework-694a588f94785431d012daa8d001f2f931aec852.zip
Add DiffJSONSerializer for updating existing objects (#8879)
This is work in progress towards using declared types for data received from the server.
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java5
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/DiffJSONSerializer.java19
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java65
-rw-r--r--src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java6
-rw-r--r--src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java84
6 files changed, 107 insertions, 79 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 530fd546db..c7ec5236b0 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -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
index 0000000000..29cb714828
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/communication/DiffJSONSerializer.java
@@ -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);
+}
diff --git a/src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java b/src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java
index f7b3df6b05..fe879b2fa7 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java
@@ -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);
/**
diff --git a/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java b/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
index 8df92a141e..8d22481783 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
@@ -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));
}
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java b/src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
index 2ee7df7f6d..1ae8cc4755 100644
--- a/src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
+++ b/src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
@@ -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;
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
index bc031f4bdb..6aa6b073ee 100644
--- a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
+++ b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
@@ -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;");
+ }
}