Browse Source

Added support for serializing enums (#8675)

Changed JSONSerializer to use JSONValue instead of JSONObject
tags/7.0.0.alpha3
Artur Signell 12 years ago
parent
commit
43794ef1b8

+ 3
- 2
src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java View File

@@ -5,6 +5,7 @@
package com.vaadin.terminal.gwt.client.communication;

import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap;
import com.vaadin.terminal.gwt.server.JsonCodec;
@@ -40,7 +41,7 @@ public interface JSONSerializer<T> {
* references to paintables
* @return A deserialized object
*/
T deserialize(JSONObject jsonValue, T target, ConnectorMap idMapper,
T deserialize(JSONValue jsonValue, T target, ConnectorMap idMapper,
ApplicationConnection connection);

/**
@@ -56,7 +57,7 @@ public interface JSONSerializer<T> {
* references to paintables
* @return A JSON serialized version of the object
*/
JSONObject serialize(T value, ConnectorMap idMapper,
JSONValue serialize(T value, ConnectorMap idMapper,
ApplicationConnection connection);

}

+ 5
- 4
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java View File

@@ -15,6 +15,7 @@ import java.util.Set;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Connector;
import com.vaadin.terminal.gwt.client.ConnectorMap;
@@ -52,7 +53,7 @@ public class JsonDecoder {
return decodeValue(type, jsonArray.get(1), target, idMapper, connection);
}

private static Object decodeValue(String variableType, Object value,
private static Object decodeValue(String variableType, JSONValue value,
Object target, ConnectorMap idMapper,
ApplicationConnection connection) {
Object val = null;
@@ -91,15 +92,15 @@ public class JsonDecoder {
} else if (JsonEncoder.VTYPE_CONNECTOR.equals(variableType)) {
val = idMapper.getConnector(((JSONString) value).stringValue());
} else {
return decodeObject(variableType, (JSONObject) value, target,
idMapper, connection);
return decodeObject(variableType, value, target, idMapper,
connection);
}

return val;
}

private static Object decodeObject(String variableType,
JSONObject encodedValue, Object target, ConnectorMap idMapper,
JSONValue encodedValue, Object target, ConnectorMap idMapper,
ApplicationConnection connection) {
// object, class name as type
JSONSerializer<Object> serializer = connection.getSerializerMap()

+ 9
- 2
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java View File

@@ -80,6 +80,9 @@ public class JsonEncoder {
JSONBoolean.getInstance((Boolean) value));
} else if (value instanceof Object[]) {
return encodeObjectArray((Object[]) value, connectorMap, connection);
} else if (value instanceof Enum) {
Enum e = (Enum) value;
return encodeEnum(e, connectorMap, connection);
} else if (value instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) value;
JSONObject jsonMap = new JSONObject();
@@ -127,6 +130,12 @@ public class JsonEncoder {
}
}

private static JSONValue encodeEnum(Enum e, ConnectorMap connectorMap,
ApplicationConnection connection) {
return combineTypeAndValue(e.getClass().getName(),
new JSONString(e.toString()));
}

private static JSONValue encodeObjectArray(Object[] array,
ConnectorMap connectorMap, ApplicationConnection connection) {
JSONArray jsonArray = new JSONArray();
@@ -193,8 +202,6 @@ public class JsonEncoder {
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[]) {
return VTYPE_STRINGARRAY;
} else if (value instanceof Object[]) {

+ 6
- 4
src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java View File

@@ -6,16 +6,18 @@ package com.vaadin.terminal.gwt.client.communication;
import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap;

public class URLReference_Serializer implements JSONSerializer<URLReference> {

public URLReference deserialize(JSONObject jsonValue, URLReference target,
public URLReference deserialize(JSONValue jsonValue, URLReference target,
ConnectorMap idMapper, ApplicationConnection connection) {
URLReference reference = GWT.create(URLReference.class);
if (jsonValue.containsKey("URL")) {
JSONArray jsonURL = (JSONArray) jsonValue.get("URL");
JSONObject json = (JSONObject) jsonValue;
if (json.containsKey("URL")) {
JSONArray jsonURL = (JSONArray) json.get("URL");
String URL = (String) JsonDecoder.decodeValue(jsonURL, null,
idMapper, connection);
reference.setURL(connection.translateVaadinUri(URL));
@@ -23,7 +25,7 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> {
return reference;
}

public JSONObject serialize(URLReference value, ConnectorMap idMapper,
public JSONValue serialize(URLReference value, ConnectorMap idMapper,
ApplicationConnection connection) {
JSONObject json = new JSONObject();
json.put("URL",

+ 18
- 0
src/com/vaadin/terminal/gwt/server/JsonCodec.java View File

@@ -321,6 +321,11 @@ public class JsonCodec implements Serializable {
}
}

private static Object decodeEnum(Class<? extends Enum> cls, JSONObject value) {
String enumIdentifier = String.valueOf(value);
return Enum.valueOf(cls, enumIdentifier);
}

private static String[] decodeStringArray(JSONArray jsonArray)
throws JSONException {
int length = jsonArray.length();
@@ -384,6 +389,11 @@ public class JsonCodec implements Serializable {
throws JSONException {

Class<?> targetClass = getClassForType(targetType);
if (Enum.class.isAssignableFrom(targetClass)) {
return decodeEnum(targetClass.asSubclass(Enum.class),
serializedObject);
}

try {
Object decodedObject = targetClass.newInstance();
for (PropertyDescriptor pd : Introspector.getBeanInfo(targetClass)
@@ -484,6 +494,8 @@ public class JsonCodec implements Serializable {
} else if (internalTransportType != null) {
return combineTypeAndValue(internalTransportType,
String.valueOf(value));
} else if (value instanceof Enum) {
return encodeEnum((Enum) value, application);
} else {
// Any object that we do not know how to encode we encode by looping
// through fields
@@ -558,6 +570,12 @@ public class JsonCodec implements Serializable {
return false;
}

private static JSONArray encodeEnum(Enum e, Application application)
throws JSONException {
String enumIdentifier = e.name();
return combineTypeAndValue(e.getClass().getName(), enumIdentifier);
}

private static JSONArray encodeArrayContents(Object[] array,
Application application) throws JSONException {
JSONArray jsonArray = new JSONArray();

+ 92
- 39
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java View File

@@ -16,12 +16,16 @@ import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JEnumConstant;
import com.google.gwt.core.ext.typeinfo.JEnumType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
@@ -89,6 +93,8 @@ public class SerializerGenerator extends Generator {
if (printWriter == null) {
return;
}
boolean isEnum = (beanType.isEnum() != null);

Date date = new Date();
TypeOracle typeOracle = context.getTypeOracle();
String beanQualifiedSourceName = beanType.getQualifiedSourceName();
@@ -117,7 +123,7 @@ public class SerializerGenerator extends Generator {

// public JSONValue serialize(Object value, ConnectorMap idMapper,
// ApplicationConnection connection) {
sourceWriter.println("public " + JSONObject.class.getName()
sourceWriter.println("public " + JSONValue.class.getName()
+ " serialize(" + beanQualifiedSourceName + " value, "
+ ConnectorMap.class.getName() + " idMapper, "
+ ApplicationConnection.class.getName() + " connection) {");
@@ -125,48 +131,75 @@ public class SerializerGenerator extends Generator {
// MouseEventDetails castedValue = (MouseEventDetails) value;
sourceWriter.println(beanQualifiedSourceName + " castedValue = ("
+ beanQualifiedSourceName + ") value;");
// JSONObject json = new JSONObject();
sourceWriter.println(JSONObject.class.getName() + " json = new "
+ JSONObject.class.getName() + "();");

for (JMethod setterMethod : getSetters(beanType)) {
String setterName = setterMethod.getName();
String fieldName = setterName.substring(3); // setZindex() -> ZIndex
String getterName = findGetter(beanType, setterMethod);

if (getterName == null) {
logger.log(TreeLogger.ERROR, "No getter found for " + fieldName
+ ". Serialization will likely fail");
}
// json.put("button",
// JsonEncoder.encode(castedValue.getButton(), idMapper,
// connection));
sourceWriter.println("json.put(\"" + fieldName + "\", "
+ JsonEncoder.class.getName() + ".encode(castedValue."
+ getterName + "(), idMapper, connection));");
if (isEnum) {
writeEnumSerializer(logger, sourceWriter, beanType);
} else {
writeBeanSerializer(logger, sourceWriter, beanType);
}
// return json;
sourceWriter.println("return json;");
// }
sourceWriter.println("}");

// Deserializer
sourceWriter.println("public " + beanQualifiedSourceName
+ " deserialize(" + JSONObject.class.getName() + " jsonValue, "
+ " deserialize(" + JSONValue.class.getName() + " jsonValue, "
+ beanQualifiedSourceName + " target, "
+ ConnectorMap.class.getName() + " idMapper, "
+ ApplicationConnection.class.getName() + " connection) {");
sourceWriter.indent();

if (isEnum) {
writeEnumDeserializer(logger, sourceWriter, beanType.isEnum());
} else {
writeBeanDeserializer(logger, sourceWriter, beanType);
}
sourceWriter.println("}");
sourceWriter.outdent();

// End of class
sourceWriter.println("}");
sourceWriter.outdent();

// commit generated class
context.commit(logger, printWriter);
logger.log(TreeLogger.INFO, "Generated Serializer class "
+ getFullyQualifiedSerializerClassName(beanType));
}

private void writeEnumDeserializer(TreeLogger logger,
SourceWriter sourceWriter, JEnumType enumType) {
sourceWriter.println("String enumIdentifier = (("
+ JSONString.class.getName() + ")jsonValue).stringValue();");
for (JEnumConstant e : enumType.getEnumConstants()) {
sourceWriter.println("if (\"" + e.getName()
+ "\".equals(enumIdentifier)) {");
sourceWriter.indent();
sourceWriter.println("return " + enumType.getQualifiedSourceName()
+ "." + e.getName() + ";");
sourceWriter.outdent();
sourceWriter.println("}");
}
sourceWriter.println("return null;");
}

private void writeBeanDeserializer(TreeLogger logger,
SourceWriter sourceWriter, JClassType beanType) {
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("}");

// JSONOBject json = (JSONObject)jsonValue;
sourceWriter.println(JSONObject.class.getName() + " json = ("
+ JSONObject.class.getName() + ")jsonValue;");

for (JMethod method : getSetters(beanType)) {
String setterName = method.getName();
String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
@@ -175,14 +208,14 @@ public class SerializerGenerator extends Generator {
logger.log(Type.DEBUG, "* Processing field " + fieldName + " in "
+ beanQualifiedSourceName + " (" + beanType.getName() + ")");

// if (jsonValue.containsKey("height")) {
sourceWriter.println("if (jsonValue.containsKey(\"" + fieldName
// if (json.containsKey("height")) {
sourceWriter.println("if (json.containsKey(\"" + fieldName
+ "\")) {");
sourceWriter.indent();
String jsonFieldName = "json_" + fieldName;
// JSONArray json_Height = (JSONArray) jsonValue.get("height");
// JSONArray json_Height = (JSONArray) json.get("height");
sourceWriter.println("JSONArray " + jsonFieldName
+ " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");
+ " = (JSONArray) json.get(\"" + fieldName + "\");");

String fieldType;
String getterName = "get" + fieldName;
@@ -228,17 +261,41 @@ public class SerializerGenerator extends Generator {

// return target;
sourceWriter.println("return target;");
sourceWriter.println("}");
sourceWriter.outdent();

// End of class
sourceWriter.println("}");
sourceWriter.outdent();
}

// commit generated class
context.commit(logger, printWriter);
logger.log(TreeLogger.INFO, "Generated Serializer class "
+ getFullyQualifiedSerializerClassName(beanType));
private void writeEnumSerializer(TreeLogger logger,
SourceWriter sourceWriter, JClassType beanType) {
// return new JSONString(castedValue.name());
sourceWriter.println("return new " + JSONString.class.getName()
+ "(castedValue.name());");
}

private void writeBeanSerializer(TreeLogger logger,
SourceWriter sourceWriter, JClassType beanType) {

// JSONObject json = new JSONObject();
sourceWriter.println(JSONObject.class.getName() + " json = new "
+ JSONObject.class.getName() + "();");

for (JMethod setterMethod : getSetters(beanType)) {
String setterName = setterMethod.getName();
String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
String getterName = findGetter(beanType, setterMethod);

if (getterName == null) {
logger.log(TreeLogger.ERROR, "No getter found for " + fieldName
+ ". Serialization will likely fail");
}
// json.put("button",
// JsonEncoder.encode(castedValue.getButton(), idMapper,
// connection));
sourceWriter.println("json.put(\"" + fieldName + "\", "
+ JsonEncoder.class.getName() + ".encode(castedValue."
+ getterName + "(), idMapper, connection));");
}
// return json;
sourceWriter.println("return json;");

}

@@ -283,10 +340,6 @@ public class SerializerGenerator extends Generator {
return setterMethods;
}

private String decapitalize(String name) {
return name.substring(0, 1).toLowerCase() + name.substring(1);
}

private static String getSerializerSimpleClassName(JClassType beanType) {
return getSimpleClassName(beanType) + "_Serializer";
}

+ 0
- 3
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java View File

@@ -301,9 +301,6 @@ public class SerializerMapGenerator extends Generator {
if (setterType.isArray() != null) {
return true;
}
if (setterType.isEnum() != null) {
return true;
}
if (setterType.isPrimitive() != null) {
return true;
}

Loading…
Cancel
Save