Changed JSONSerializer to use JSONValue instead of JSONObjecttags/7.0.0.alpha3
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); | ||||
} | } |
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() |
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[]) { |
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", |
} | } | ||||
} | } | ||||
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(); |
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"; | ||||
} | } |
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; | ||||
} | } |