瀏覽代碼

Added support for serializing enums (#8675)

Changed JSONSerializer to use JSONValue instead of JSONObject
tags/7.0.0.alpha3
Artur Signell 12 年之前
父節點
當前提交
43794ef1b8

+ 3
- 2
src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java 查看文件

package com.vaadin.terminal.gwt.client.communication; package com.vaadin.terminal.gwt.client.communication;


import com.google.gwt.json.client.JSONObject; 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.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.ConnectorMap;
import com.vaadin.terminal.gwt.server.JsonCodec; import com.vaadin.terminal.gwt.server.JsonCodec;
* references to paintables * references to paintables
* @return A deserialized object * @return A deserialized object
*/ */
T deserialize(JSONObject jsonValue, T target, ConnectorMap idMapper,
T deserialize(JSONValue jsonValue, T target, ConnectorMap idMapper,
ApplicationConnection connection); ApplicationConnection connection);


/** /**
* references to paintables * references to paintables
* @return A JSON serialized version of the object * @return A JSON serialized version of the object
*/ */
JSONObject serialize(T value, ConnectorMap idMapper,
JSONValue serialize(T value, ConnectorMap idMapper,
ApplicationConnection connection); ApplicationConnection connection);


} }

+ 5
- 4
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java 查看文件

import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString; 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.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.Connector;
import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.ConnectorMap;
return decodeValue(type, jsonArray.get(1), target, idMapper, connection); 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, Object target, ConnectorMap idMapper,
ApplicationConnection connection) { ApplicationConnection connection) {
Object val = null; Object val = null;
} else if (JsonEncoder.VTYPE_CONNECTOR.equals(variableType)) { } else if (JsonEncoder.VTYPE_CONNECTOR.equals(variableType)) {
val = idMapper.getConnector(((JSONString) value).stringValue()); val = idMapper.getConnector(((JSONString) value).stringValue());
} else { } else {
return decodeObject(variableType, (JSONObject) value, target,
idMapper, connection);
return decodeObject(variableType, value, target, idMapper,
connection);
} }


return val; return val;
} }


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

+ 9
- 2
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java 查看文件

JSONBoolean.getInstance((Boolean) value)); JSONBoolean.getInstance((Boolean) value));
} else if (value instanceof Object[]) { } else if (value instanceof Object[]) {
return encodeObjectArray((Object[]) value, connectorMap, connection); 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) { } else if (value instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) value; Map<Object, Object> map = (Map<Object, Object>) value;
JSONObject jsonMap = new JSONObject(); JSONObject jsonMap = new JSONObject();
} }
} }


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, private static JSONValue encodeObjectArray(Object[] array,
ConnectorMap connectorMap, ApplicationConnection connection) { ConnectorMap connectorMap, ApplicationConnection connection) {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();
return VTYPE_LIST; return VTYPE_LIST;
} else if (value instanceof Set) { } else if (value instanceof Set) {
return VTYPE_SET; return VTYPE_SET;
} else if (value instanceof Enum) {
return VTYPE_STRING; // transported as string representation
} else if (value instanceof String[]) { } else if (value instanceof String[]) {
return VTYPE_STRINGARRAY; return VTYPE_STRINGARRAY;
} else if (value instanceof Object[]) { } else if (value instanceof Object[]) {

+ 6
- 4
src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java 查看文件

import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject; 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.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.ConnectorMap;


public class URLReference_Serializer implements JSONSerializer<URLReference> { 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) { ConnectorMap idMapper, ApplicationConnection connection) {
URLReference reference = GWT.create(URLReference.class); 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, String URL = (String) JsonDecoder.decodeValue(jsonURL, null,
idMapper, connection); idMapper, connection);
reference.setURL(connection.translateVaadinUri(URL)); reference.setURL(connection.translateVaadinUri(URL));
return reference; return reference;
} }


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

+ 18
- 0
src/com/vaadin/terminal/gwt/server/JsonCodec.java 查看文件

} }
} }


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) private static String[] decodeStringArray(JSONArray jsonArray)
throws JSONException { throws JSONException {
int length = jsonArray.length(); int length = jsonArray.length();
throws JSONException { throws JSONException {


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

try { try {
Object decodedObject = targetClass.newInstance(); Object decodedObject = targetClass.newInstance();
for (PropertyDescriptor pd : Introspector.getBeanInfo(targetClass) for (PropertyDescriptor pd : Introspector.getBeanInfo(targetClass)
} else if (internalTransportType != null) { } else if (internalTransportType != null) {
return combineTypeAndValue(internalTransportType, return combineTypeAndValue(internalTransportType,
String.valueOf(value)); String.valueOf(value));
} else if (value instanceof Enum) {
return encodeEnum((Enum) value, application);
} else { } else {
// Any object that we do not know how to encode we encode by looping // Any object that we do not know how to encode we encode by looping
// through fields // through fields
return false; 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, private static JSONArray encodeArrayContents(Object[] array,
Application application) throws JSONException { Application application) throws JSONException {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();

+ 92
- 39
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java 查看文件

import com.google.gwt.core.ext.TreeLogger.Type; import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType; 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.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType; import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject; 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.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter; import com.google.gwt.user.rebind.SourceWriter;
import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ApplicationConnection;
if (printWriter == null) { if (printWriter == null) {
return; return;
} }
boolean isEnum = (beanType.isEnum() != null);

Date date = new Date(); Date date = new Date();
TypeOracle typeOracle = context.getTypeOracle(); TypeOracle typeOracle = context.getTypeOracle();
String beanQualifiedSourceName = beanType.getQualifiedSourceName(); String beanQualifiedSourceName = beanType.getQualifiedSourceName();


// public JSONValue serialize(Object value, ConnectorMap idMapper, // public JSONValue serialize(Object value, ConnectorMap idMapper,
// ApplicationConnection connection) { // ApplicationConnection connection) {
sourceWriter.println("public " + JSONObject.class.getName()
sourceWriter.println("public " + JSONValue.class.getName()
+ " serialize(" + beanQualifiedSourceName + " value, " + " serialize(" + beanQualifiedSourceName + " value, "
+ ConnectorMap.class.getName() + " idMapper, " + ConnectorMap.class.getName() + " idMapper, "
+ ApplicationConnection.class.getName() + " connection) {"); + ApplicationConnection.class.getName() + " connection) {");
// MouseEventDetails castedValue = (MouseEventDetails) value; // MouseEventDetails castedValue = (MouseEventDetails) value;
sourceWriter.println(beanQualifiedSourceName + " castedValue = (" sourceWriter.println(beanQualifiedSourceName + " castedValue = ("
+ beanQualifiedSourceName + ") value;"); + 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("}"); sourceWriter.println("}");


// Deserializer // Deserializer
sourceWriter.println("public " + beanQualifiedSourceName sourceWriter.println("public " + beanQualifiedSourceName
+ " deserialize(" + JSONObject.class.getName() + " jsonValue, "
+ " deserialize(" + JSONValue.class.getName() + " jsonValue, "
+ beanQualifiedSourceName + " target, " + beanQualifiedSourceName + " target, "
+ ConnectorMap.class.getName() + " idMapper, " + ConnectorMap.class.getName() + " idMapper, "
+ ApplicationConnection.class.getName() + " connection) {"); + ApplicationConnection.class.getName() + " connection) {");
sourceWriter.indent(); 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) { // if (target == null) {
sourceWriter.println("if (target == null) {"); sourceWriter.println("if (target == null) {");
sourceWriter.indent(); sourceWriter.indent();

// target = GWT.create(VButtonState.class); // target = GWT.create(VButtonState.class);
sourceWriter.println("target = GWT.create(" + beanQualifiedSourceName sourceWriter.println("target = GWT.create(" + beanQualifiedSourceName
+ ".class);"); + ".class);");
sourceWriter.outdent(); sourceWriter.outdent();
sourceWriter.println("}"); sourceWriter.println("}");


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

for (JMethod method : getSetters(beanType)) { for (JMethod method : getSetters(beanType)) {
String setterName = method.getName(); String setterName = method.getName();
String fieldName = setterName.substring(3); // setZIndex() -> ZIndex String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
logger.log(Type.DEBUG, "* Processing field " + fieldName + " in " logger.log(Type.DEBUG, "* Processing field " + fieldName + " in "
+ beanQualifiedSourceName + " (" + beanType.getName() + ")"); + 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(); sourceWriter.indent();
String jsonFieldName = "json_" + fieldName; String jsonFieldName = "json_" + fieldName;
// JSONArray json_Height = (JSONArray) jsonValue.get("height");
// JSONArray json_Height = (JSONArray) json.get("height");
sourceWriter.println("JSONArray " + jsonFieldName sourceWriter.println("JSONArray " + jsonFieldName
+ " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");
+ " = (JSONArray) json.get(\"" + fieldName + "\");");


String fieldType; String fieldType;
String getterName = "get" + fieldName; String getterName = "get" + fieldName;


// return target; // return target;
sourceWriter.println("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;");


} }


return setterMethods; return setterMethods;
} }


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

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

+ 0
- 3
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java 查看文件

if (setterType.isArray() != null) { if (setterType.isArray() != null) {
return true; return true;
} }
if (setterType.isEnum() != null) {
return true;
}
if (setterType.isPrimitive() != null) { if (setterType.isPrimitive() != null) {
return true; return true;
} }

Loading…
取消
儲存