} | } | ||||
String baseTypeName = type.getBaseTypeName(); | String baseTypeName = type.getBaseTypeName(); | ||||
if (baseTypeName.endsWith("[]")) { | |||||
return decodeArray(type, (JSONArray) jsonValue, connection); | |||||
} else if (Map.class.getName().equals(baseTypeName) | |||||
if (Map.class.getName().equals(baseTypeName) | |||||
|| HashMap.class.getName().equals(baseTypeName)) { | || HashMap.class.getName().equals(baseTypeName)) { | ||||
return decodeMap(type, jsonValue, connection); | return decodeMap(type, jsonValue, connection); | ||||
} else if (List.class.getName().equals(baseTypeName) | } else if (List.class.getName().equals(baseTypeName) | ||||
} else if (Boolean.class.getName().equals(baseTypeName)) { | } else if (Boolean.class.getName().equals(baseTypeName)) { | ||||
// TODO handle properly | // TODO handle properly | ||||
return Boolean.valueOf(String.valueOf(jsonValue)); | return Boolean.valueOf(String.valueOf(jsonValue)); | ||||
} else if (Byte.class.getName().equals(baseTypeName)) { | |||||
// TODO handle properly | |||||
return Byte.valueOf(String.valueOf(jsonValue)); | |||||
} else if (Character.class.getName().equals(baseTypeName)) { | |||||
// TODO handle properly | |||||
return Character.valueOf(((JSONString) jsonValue).stringValue() | |||||
.charAt(0)); | |||||
} else if (Connector.class.getName().equals(baseTypeName)) { | } else if (Connector.class.getName().equals(baseTypeName)) { | ||||
return ConnectorMap.get(connection).getConnector( | return ConnectorMap.get(connection).getConnector( | ||||
((JSONString) jsonValue).stringValue()); | ((JSONString) jsonValue).stringValue()); | ||||
return map; | return map; | ||||
} | } | ||||
private static Object[] decodeArray(Type type, JSONArray jsonArray, | |||||
ApplicationConnection connection) { | |||||
String arrayTypeName = type.getBaseTypeName(); | |||||
String chldTypeName = arrayTypeName.substring(0, | |||||
arrayTypeName.length() - 2); | |||||
List<Object> list = decodeList(new Type(chldTypeName, null), jsonArray, | |||||
connection); | |||||
return list.toArray(new Object[list.size()]); | |||||
} | |||||
private static List<Object> decodeList(Type type, JSONArray jsonArray, | private static List<Object> decodeList(Type type, JSONArray jsonArray, | ||||
ApplicationConnection connection) { | ApplicationConnection connection) { | ||||
List<Object> tokens = new ArrayList<Object>(); | List<Object> tokens = new ArrayList<Object>(); |
import com.google.gwt.json.client.JSONArray; | import com.google.gwt.json.client.JSONArray; | ||||
import com.google.gwt.json.client.JSONBoolean; | import com.google.gwt.json.client.JSONBoolean; | ||||
import com.google.gwt.json.client.JSONNull; | import com.google.gwt.json.client.JSONNull; | ||||
import com.google.gwt.json.client.JSONNumber; | |||||
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.google.gwt.json.client.JSONValue; | ||||
return new JSONString((String) value); | return new JSONString((String) value); | ||||
} else if (value instanceof Boolean) { | } else if (value instanceof Boolean) { | ||||
return JSONBoolean.getInstance((Boolean) value); | return JSONBoolean.getInstance((Boolean) value); | ||||
} else if (value instanceof Byte) { | |||||
return new JSONNumber((Byte) value); | |||||
} else if (value instanceof Character) { | |||||
return new JSONString(String.valueOf(value)); | |||||
} else if (value instanceof Object[]) { | } else if (value instanceof Object[]) { | ||||
return encodeObjectArray((Object[]) value, restrictToInternalTypes, | return encodeObjectArray((Object[]) value, restrictToInternalTypes, | ||||
connection); | connection); |
import java.beans.Introspector; | import java.beans.Introspector; | ||||
import java.beans.PropertyDescriptor; | import java.beans.PropertyDescriptor; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.lang.reflect.Array; | |||||
import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||
import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
import java.lang.reflect.ParameterizedType; | import java.lang.reflect.ParameterizedType; | ||||
public static boolean isInternalType(Type type) { | public static boolean isInternalType(Type type) { | ||||
if (type instanceof Class && ((Class<?>) type).isPrimitive()) { | if (type instanceof Class && ((Class<?>) type).isPrimitive()) { | ||||
if (type == byte.class || type == char.class) { | |||||
// Almost all primitive types are handled internally | |||||
return false; | |||||
} | |||||
// All primitive types are handled internally | // All primitive types are handled internally | ||||
return true; | return true; | ||||
} else if (type == UidlValue.class) { | } else if (type == UidlValue.class) { | ||||
// Try to decode object using fields | // Try to decode object using fields | ||||
if (value == JSONObject.NULL) { | if (value == JSONObject.NULL) { | ||||
return null; | return null; | ||||
} else if (targetType == byte.class || targetType == Byte.class) { | |||||
return Byte.valueOf(String.valueOf(value)); | |||||
} else if (targetType == char.class || targetType == Character.class) { | |||||
return Character.valueOf(String.valueOf(value).charAt(0)); | |||||
} else if (targetType instanceof Class<?> | |||||
&& ((Class<?>) targetType).isArray()) { | |||||
// Legacy Object[] and String[] handled elsewhere, this takes care | |||||
// of generic arrays | |||||
return decodeArray((Class<?>) targetType, (JSONArray) value, | |||||
application); | |||||
} else if (targetType == JSONObject.class | } else if (targetType == JSONObject.class | ||||
|| targetType == JSONArray.class) { | || targetType == JSONArray.class) { | ||||
return value; | return value; | ||||
} | } | ||||
} | } | ||||
private static Object decodeArray(Class<?> targetType, JSONArray value, | |||||
Application application) throws JSONException { | |||||
Class<?> componentType = targetType.getComponentType(); | |||||
Object array = Array.newInstance(componentType, value.length()); | |||||
for (int i = 0; i < value.length(); i++) { | |||||
Object decodedValue = decodeInternalOrCustomType(componentType, | |||||
value.get(i), application); | |||||
Array.set(array, i, decodedValue); | |||||
} | |||||
return array; | |||||
} | |||||
/** | /** | ||||
* Decodes a value that is of an internal type. | * Decodes a value that is of an internal type. | ||||
* <p> | * <p> | ||||
return application.getConnector(stringValue); | return application.getConnector(stringValue); | ||||
} | } | ||||
// Standard Java types | |||||
// Legacy types | |||||
if (JsonEncoder.VTYPE_STRING.equals(transportType)) { | if (JsonEncoder.VTYPE_STRING.equals(transportType)) { | ||||
return stringValue; | return stringValue; | ||||
return value; | return value; | ||||
} else if (value instanceof Number) { | } else if (value instanceof Number) { | ||||
return value; | return value; | ||||
} else if (value instanceof Character) { | |||||
// Character is not a Number | |||||
return value; | |||||
} else if (value instanceof Collection) { | } else if (value instanceof Collection) { | ||||
Collection<?> collection = (Collection<?>) value; | Collection<?> collection = (Collection<?>) value; | ||||
JSONArray jsonArray = encodeCollection(valueType, collection, | JSONArray jsonArray = encodeCollection(valueType, collection, | ||||
application); | application); | ||||
return jsonArray; | return jsonArray; | ||||
} else if (value instanceof Object[]) { | |||||
Object[] array = (Object[]) value; | |||||
JSONArray jsonArray = encodeArrayContents(array, application); | |||||
} else if (valueType instanceof Class<?> | |||||
&& ((Class<?>) valueType).isArray()) { | |||||
JSONArray jsonArray = encodeArrayContents(value, application); | |||||
return jsonArray; | return jsonArray; | ||||
} else if (value instanceof Map) { | } else if (value instanceof Map) { | ||||
Object jsonMap = encodeMap(valueType, (Map<?, ?>) value, | Object jsonMap = encodeMap(valueType, (Map<?, ?>) value, | ||||
return e.name(); | return e.name(); | ||||
} | } | ||||
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(); | ||||
for (Object o : array) { | |||||
jsonArray.put(encode(o, null, null, application)); | |||||
Class<?> componentType = array.getClass().getComponentType(); | |||||
for (int i = 0; i < Array.getLength(array); i++) { | |||||
jsonArray.put(encode(Array.get(array, i), null, componentType, | |||||
application)); | |||||
} | } | ||||
return jsonArray; | return jsonArray; | ||||
} | } |
if (i != 0) { | if (i != 0) { | ||||
sourceWriter.print(", "); | sourceWriter.print(", "); | ||||
} | } | ||||
sourceWriter.print("(" | |||||
+ parameterType.getQualifiedSourceName() | |||||
String parameterTypeName = getBoxedTypeName(parameterType); | |||||
sourceWriter.print("(" + parameterTypeName | |||||
+ ") parameters[" + i + "]"); | + ") parameters[" + i + "]"); | ||||
} | } | ||||
sourceWriter.println(");"); | sourceWriter.println(");"); | ||||
} | } | ||||
public static void writeTypeCreator(SourceWriter sourceWriter, JType type) { | public static void writeTypeCreator(SourceWriter sourceWriter, JType type) { | ||||
String typeName; | |||||
if (type.isPrimitive() != null) { | |||||
// Used boxed types for primitives | |||||
typeName = type.isPrimitive().getQualifiedBoxedSourceName(); | |||||
} else { | |||||
typeName = type.getErasedType().getQualifiedBinaryName(); | |||||
} | |||||
String typeName = getBoxedTypeName(type); | |||||
sourceWriter.print("new Type(\"" + typeName + "\", "); | sourceWriter.print("new Type(\"" + typeName + "\", "); | ||||
JParameterizedType parameterized = type.isParameterized(); | JParameterizedType parameterized = type.isParameterized(); | ||||
if (parameterized != null) { | if (parameterized != null) { | ||||
sourceWriter.print(")"); | sourceWriter.print(")"); | ||||
} | } | ||||
public static String getBoxedTypeName(JType type) { | |||||
if (type.isPrimitive() != null) { | |||||
// Used boxed types for primitives | |||||
return type.isPrimitive().getQualifiedBoxedSourceName(); | |||||
} else { | |||||
return type.getErasedType().getQualifiedSourceName(); | |||||
} | |||||
} | |||||
private String getInvokeMethodName(JClassType type) { | private String getInvokeMethodName(JClassType type) { | ||||
return "invoke" + type.getQualifiedSourceName().replaceAll("\\.", "_"); | return "invoke" + type.getQualifiedSourceName().replaceAll("\\.", "_"); | ||||
} | } |
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Date; | |||||
import java.util.HashSet; | import java.util.HashSet; | ||||
import java.util.List; | import java.util.List; | ||||
import com.google.gwt.core.ext.TreeLogger; | import com.google.gwt.core.ext.TreeLogger; | ||||
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.JArrayType; | |||||
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.JEnumConstant; | ||||
import com.google.gwt.core.ext.typeinfo.JEnumType; | 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.TypeOracleException; | |||||
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.google.gwt.json.client.JSONValue; | ||||
public class SerializerGenerator extends Generator { | public class SerializerGenerator extends Generator { | ||||
private static final String SUBTYPE_SEPARATOR = "___"; | private static final String SUBTYPE_SEPARATOR = "___"; | ||||
private static String beanSerializerPackageName = SerializerMap.class | |||||
private static String serializerPackageName = SerializerMap.class | |||||
.getPackage().getName(); | .getPackage().getName(); | ||||
@Override | @Override | ||||
public String generate(TreeLogger logger, GeneratorContext context, | public String generate(TreeLogger logger, GeneratorContext context, | ||||
String beanTypeName) throws UnableToCompleteException { | |||||
JClassType beanType = context.getTypeOracle().findType(beanTypeName); | |||||
String beanSerializerClassName = getSerializerSimpleClassName(beanType); | |||||
String typeName) throws UnableToCompleteException { | |||||
JClassType type; | |||||
try { | |||||
type = (JClassType) context.getTypeOracle().parse(typeName); | |||||
} catch (TypeOracleException e1) { | |||||
logger.log(Type.ERROR, "Could not find type " + typeName, e1); | |||||
throw new UnableToCompleteException(); | |||||
} | |||||
String serializerClassName = getSerializerSimpleClassName(type); | |||||
try { | try { | ||||
// Generate class source code | // Generate class source code | ||||
generateClass(logger, context, beanType, beanSerializerPackageName, | |||||
beanSerializerClassName); | |||||
generateClass(logger, context, type, serializerPackageName, | |||||
serializerClassName); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.log(TreeLogger.ERROR, "SerializerGenerator failed for " | logger.log(TreeLogger.ERROR, "SerializerGenerator failed for " | ||||
+ beanType.getQualifiedSourceName(), e); | |||||
+ type.getQualifiedSourceName(), e); | |||||
throw new UnableToCompleteException(); | throw new UnableToCompleteException(); | ||||
} | } | ||||
// return the fully qualifed name of the class generated | // return the fully qualifed name of the class generated | ||||
return getFullyQualifiedSerializerClassName(beanType); | |||||
return getFullyQualifiedSerializerClassName(type); | |||||
} | } | ||||
/** | /** | ||||
* Logger object | * Logger object | ||||
* @param context | * @param context | ||||
* Generator context | * Generator context | ||||
* @param beanType | |||||
* @param type | |||||
* @param beanTypeName | * @param beanTypeName | ||||
* bean type for which the serializer is to be generated | * bean type for which the serializer is to be generated | ||||
* @param beanSerializerTypeName | * @param beanSerializerTypeName | ||||
* @throws UnableToCompleteException | * @throws UnableToCompleteException | ||||
*/ | */ | ||||
private void generateClass(TreeLogger logger, GeneratorContext context, | private void generateClass(TreeLogger logger, GeneratorContext context, | ||||
JClassType beanType, String serializerPackageName, | |||||
JClassType type, String serializerPackageName, | |||||
String serializerClassName) throws UnableToCompleteException { | String serializerClassName) throws UnableToCompleteException { | ||||
// get print writer that receives the source code | // get print writer that receives the source code | ||||
PrintWriter printWriter = null; | PrintWriter printWriter = null; | ||||
if (printWriter == null) { | if (printWriter == null) { | ||||
return; | return; | ||||
} | } | ||||
boolean isEnum = (beanType.isEnum() != null); | |||||
boolean isEnum = (type.isEnum() != null); | |||||
boolean isArray = (type.isArray() != null); | |||||
Date date = new Date(); | |||||
TypeOracle typeOracle = context.getTypeOracle(); | |||||
String beanQualifiedSourceName = beanType.getQualifiedSourceName(); | |||||
String qualifiedSourceName = type.getQualifiedSourceName(); | |||||
logger.log(Type.DEBUG, "Processing serializable type " | logger.log(Type.DEBUG, "Processing serializable type " | ||||
+ beanQualifiedSourceName + "..."); | |||||
+ qualifiedSourceName + "..."); | |||||
// init composer, set class properties, create source writer | // init composer, set class properties, create source writer | ||||
ClassSourceFileComposerFactory composer = null; | ClassSourceFileComposerFactory composer = null; | ||||
composer.addImport(JsonDecoder.class.getName()); | composer.addImport(JsonDecoder.class.getName()); | ||||
// composer.addImport(VaadinSerializer.class.getName()); | // composer.addImport(VaadinSerializer.class.getName()); | ||||
if (isEnum) { | |||||
if (isEnum || isArray) { | |||||
composer.addImplementedInterface(JSONSerializer.class.getName() | composer.addImplementedInterface(JSONSerializer.class.getName() | ||||
+ "<" + beanQualifiedSourceName + ">"); | |||||
+ "<" + qualifiedSourceName + ">"); | |||||
} else { | } else { | ||||
composer.addImplementedInterface(DiffJSONSerializer.class.getName() | composer.addImplementedInterface(DiffJSONSerializer.class.getName() | ||||
+ "<" + beanQualifiedSourceName + ">"); | |||||
+ "<" + qualifiedSourceName + ">"); | |||||
} | } | ||||
SourceWriter sourceWriter = composer.createSourceWriter(context, | SourceWriter sourceWriter = composer.createSourceWriter(context, | ||||
// public JSONValue serialize(Object value, | // public JSONValue serialize(Object value, | ||||
// ApplicationConnection connection) { | // ApplicationConnection connection) { | ||||
sourceWriter.println("public " + JSONValue.class.getName() | sourceWriter.println("public " + JSONValue.class.getName() | ||||
+ " serialize(" + beanQualifiedSourceName + " value, " | |||||
+ " serialize(" + qualifiedSourceName + " value, " | |||||
+ ApplicationConnection.class.getName() + " connection) {"); | + ApplicationConnection.class.getName() + " connection) {"); | ||||
sourceWriter.indent(); | sourceWriter.indent(); | ||||
// MouseEventDetails castedValue = (MouseEventDetails) value; | // MouseEventDetails castedValue = (MouseEventDetails) value; | ||||
sourceWriter.println(beanQualifiedSourceName + " castedValue = (" | |||||
+ beanQualifiedSourceName + ") value;"); | |||||
sourceWriter.println(qualifiedSourceName + " castedValue = (" | |||||
+ qualifiedSourceName + ") value;"); | |||||
if (isEnum) { | if (isEnum) { | ||||
writeEnumSerializer(logger, sourceWriter, beanType); | |||||
writeEnumSerializer(logger, sourceWriter, type); | |||||
} else if (isArray) { | |||||
writeArraySerializer(logger, sourceWriter, type.isArray()); | |||||
} else { | } else { | ||||
writeBeanSerializer(logger, sourceWriter, beanType); | |||||
writeBeanSerializer(logger, sourceWriter, type); | |||||
} | } | ||||
// } | // } | ||||
sourceWriter.outdent(); | sourceWriter.outdent(); | ||||
// Updater | // Updater | ||||
// public void update(T target, Type type, JSONValue jsonValue, | // public void update(T target, Type type, JSONValue jsonValue, | ||||
// ApplicationConnection connection); | // ApplicationConnection connection); | ||||
if (!isEnum) { | |||||
sourceWriter.println("public void update(" | |||||
+ beanQualifiedSourceName + " target, Type type, " | |||||
+ JSONValue.class.getName() + " jsonValue, " | |||||
+ ApplicationConnection.class.getName() + " connection) {"); | |||||
if (!isEnum && !isArray) { | |||||
sourceWriter.println("public void update(" + qualifiedSourceName | |||||
+ " target, Type type, " + JSONValue.class.getName() | |||||
+ " jsonValue, " + ApplicationConnection.class.getName() | |||||
+ " connection) {"); | |||||
sourceWriter.indent(); | sourceWriter.indent(); | ||||
writeBeanDeserializer(logger, sourceWriter, beanType); | |||||
writeBeanDeserializer(logger, sourceWriter, type); | |||||
sourceWriter.outdent(); | sourceWriter.outdent(); | ||||
sourceWriter.println("}"); | sourceWriter.println("}"); | ||||
// Deserializer | // Deserializer | ||||
// T deserialize(Type type, JSONValue jsonValue, ApplicationConnection | // T deserialize(Type type, JSONValue jsonValue, ApplicationConnection | ||||
// connection); | // connection); | ||||
sourceWriter.println("public " + beanQualifiedSourceName | |||||
sourceWriter.println("public " + qualifiedSourceName | |||||
+ " deserialize(Type type, " + JSONValue.class.getName() | + " deserialize(Type type, " + JSONValue.class.getName() | ||||
+ " jsonValue, " + ApplicationConnection.class.getName() | + " jsonValue, " + ApplicationConnection.class.getName() | ||||
+ " connection) {"); | + " connection) {"); | ||||
sourceWriter.indent(); | sourceWriter.indent(); | ||||
if (isEnum) { | if (isEnum) { | ||||
writeEnumDeserializer(logger, sourceWriter, beanType.isEnum()); | |||||
writeEnumDeserializer(logger, sourceWriter, type.isEnum()); | |||||
} else if (isArray) { | |||||
writeArrayDeserializer(logger, sourceWriter, type.isArray()); | |||||
} else { | } else { | ||||
sourceWriter.println(beanQualifiedSourceName | |||||
+ " target = GWT.create(" + beanQualifiedSourceName | |||||
+ ".class);"); | |||||
sourceWriter.println(qualifiedSourceName + " target = GWT.create(" | |||||
+ qualifiedSourceName + ".class);"); | |||||
sourceWriter | sourceWriter | ||||
.println("update(target, type, jsonValue, connection);"); | .println("update(target, type, jsonValue, connection);"); | ||||
// return target; | // return target; | ||||
// commit generated class | // commit generated class | ||||
context.commit(logger, printWriter); | context.commit(logger, printWriter); | ||||
logger.log(TreeLogger.INFO, "Generated Serializer class " | logger.log(TreeLogger.INFO, "Generated Serializer class " | ||||
+ getFullyQualifiedSerializerClassName(beanType)); | |||||
+ getFullyQualifiedSerializerClassName(type)); | |||||
} | } | ||||
private void writeEnumDeserializer(TreeLogger logger, | private void writeEnumDeserializer(TreeLogger logger, | ||||
sourceWriter.println("return null;"); | sourceWriter.println("return null;"); | ||||
} | } | ||||
private void writeArrayDeserializer(TreeLogger logger, | |||||
SourceWriter sourceWriter, JArrayType type) { | |||||
JType leafType = type.getLeafType(); | |||||
int rank = type.getRank(); | |||||
sourceWriter.println(JSONArray.class.getName() | |||||
+ " jsonArray = jsonValue.isArray();"); | |||||
// Type value = new Type[jsonArray.size()][][]; | |||||
sourceWriter.print(type.getQualifiedSourceName() + " value = new " | |||||
+ leafType.getQualifiedSourceName() + "[jsonArray.size()]"); | |||||
for (int i = 1; i < rank; i++) { | |||||
sourceWriter.print("[]"); | |||||
} | |||||
sourceWriter.println(";"); | |||||
sourceWriter.println("for(int i = 0 ; i < value.length; i++) {"); | |||||
sourceWriter.indent(); | |||||
JType componentType = type.getComponentType(); | |||||
sourceWriter.print("value[i] = (" | |||||
+ GeneratedRpcMethodProviderGenerator | |||||
.getBoxedTypeName(componentType) + ") " | |||||
+ JsonDecoder.class.getName() + ".decodeValue("); | |||||
GeneratedRpcMethodProviderGenerator.writeTypeCreator(sourceWriter, | |||||
componentType); | |||||
sourceWriter.print(", jsonArray.get(i), null, connection)"); | |||||
sourceWriter.println(";"); | |||||
sourceWriter.outdent(); | |||||
sourceWriter.println("}"); | |||||
sourceWriter.println("return value;"); | |||||
} | |||||
private void writeBeanDeserializer(TreeLogger logger, | private void writeBeanDeserializer(TreeLogger logger, | ||||
SourceWriter sourceWriter, JClassType beanType) { | SourceWriter sourceWriter, JClassType beanType) { | ||||
String beanQualifiedSourceName = beanType.getQualifiedSourceName(); | String beanQualifiedSourceName = beanType.getQualifiedSourceName(); | ||||
+ "(castedValue.name());"); | + "(castedValue.name());"); | ||||
} | } | ||||
private void writeArraySerializer(TreeLogger logger, | |||||
SourceWriter sourceWriter, JArrayType array) { | |||||
sourceWriter.println(JSONArray.class.getName() + " values = new " | |||||
+ JSONArray.class.getName() + "();"); | |||||
JType componentType = array.getComponentType(); | |||||
// JPrimitiveType primitive = componentType.isPrimitive(); | |||||
sourceWriter.println("for (int i = 0; i < castedValue.length; i++) {"); | |||||
sourceWriter.indent(); | |||||
sourceWriter.print("values.set(i, "); | |||||
sourceWriter.print(JsonEncoder.class.getName() | |||||
+ ".encode(castedValue[i], false, connection)"); | |||||
sourceWriter.println(");"); | |||||
sourceWriter.outdent(); | |||||
sourceWriter.println("}"); | |||||
sourceWriter.println("return values;"); | |||||
} | |||||
private void writeBeanSerializer(TreeLogger logger, | private void writeBeanSerializer(TreeLogger logger, | ||||
SourceWriter sourceWriter, JClassType beanType) | SourceWriter sourceWriter, JClassType beanType) | ||||
throws UnableToCompleteException { | throws UnableToCompleteException { | ||||
return getSimpleClassName(beanType) + "_Serializer"; | return getSimpleClassName(beanType) + "_Serializer"; | ||||
} | } | ||||
private static String getSimpleClassName(JClassType type) { | |||||
if (type.isMemberType()) { | |||||
private static String getSimpleClassName(JType type) { | |||||
JArrayType arrayType = type.isArray(); | |||||
if (arrayType != null) { | |||||
return "Array" + getSimpleClassName(arrayType.getComponentType()); | |||||
} | |||||
JClassType classType = type.isClass(); | |||||
if (classType != null && classType.isMemberType()) { | |||||
// Assumed to be static sub class | // Assumed to be static sub class | ||||
String baseName = getSimpleClassName(type.getEnclosingType()); | |||||
String baseName = getSimpleClassName(classType.getEnclosingType()); | |||||
String name = baseName + SUBTYPE_SEPARATOR | String name = baseName + SUBTYPE_SEPARATOR | ||||
+ type.getSimpleSourceName(); | + type.getSimpleSourceName(); | ||||
return name; | return name; | ||||
} | } | ||||
public static String getFullyQualifiedSerializerClassName(JClassType type) { | public static String getFullyQualifiedSerializerClassName(JClassType type) { | ||||
return beanSerializerPackageName + "." | |||||
+ getSerializerSimpleClassName(type); | |||||
return serializerPackageName + "." + getSerializerSimpleClassName(type); | |||||
} | } | ||||
} | } |
import com.google.gwt.core.ext.TreeLogger; | import com.google.gwt.core.ext.TreeLogger; | ||||
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.JArrayType; | |||||
import com.google.gwt.core.ext.typeinfo.JClassType; | import com.google.gwt.core.ext.typeinfo.JClassType; | ||||
import com.google.gwt.core.ext.typeinfo.JMethod; | import com.google.gwt.core.ext.typeinfo.JMethod; | ||||
import com.google.gwt.core.ext.typeinfo.JParameterizedType; | import com.google.gwt.core.ext.typeinfo.JParameterizedType; | ||||
JClassType javaSerializable = typeOracle.findType(Serializable.class | JClassType javaSerializable = typeOracle.findType(Serializable.class | ||||
.getName()); | .getName()); | ||||
for (JClassType type : typesNeedingSerializers) { | for (JClassType type : typesNeedingSerializers) { | ||||
if (type.isArray() != null) { | |||||
// Don't check for arrays | |||||
continue; | |||||
} | |||||
boolean serializable = type.isAssignableTo(javaSerializable); | boolean serializable = type.isAssignableTo(javaSerializable); | ||||
if (!serializable) { | if (!serializable) { | ||||
logger.log( | logger.log( | ||||
// TODO cache serializer instances in a map | // TODO cache serializer instances in a map | ||||
for (JClassType type : typesNeedingSerializers) { | for (JClassType type : typesNeedingSerializers) { | ||||
sourceWriter.println("if (type.equals(\"" | |||||
+ type.getQualifiedBinaryName() + "\")) {"); | |||||
sourceWriter.print("if (type.equals(\"" | |||||
+ type.getQualifiedSourceName() + "\")"); | |||||
if (type instanceof JArrayType) { | |||||
// Also add binary name to support encoding based on | |||||
// object.getClass().getName() | |||||
sourceWriter.print("||type.equals(\"" + type.getJNISignature() | |||||
+ "\")"); | |||||
} | |||||
sourceWriter.println(") {"); | |||||
sourceWriter.indent(); | sourceWriter.indent(); | ||||
String serializerName = SerializerGenerator | String serializerName = SerializerGenerator | ||||
.getFullyQualifiedSerializerClassName(type); | .getFullyQualifiedSerializerClassName(type); | ||||
serializableTypes.add(typeClass); | serializableTypes.add(typeClass); | ||||
findSubTypesNeedingSerializers(typeClass, serializableTypes); | findSubTypesNeedingSerializers(typeClass, serializableTypes); | ||||
} | } | ||||
// Generate (n-1)-dimensional array serializer for n-dimensional array | |||||
JArrayType arrayType = type.isArray(); | |||||
if (arrayType != null) { | |||||
serializableTypes.add(arrayType); | |||||
addTypeIfNeeded(serializableTypes, arrayType.getComponentType()); | |||||
} | |||||
} | } | ||||
Set<Class<?>> frameworkHandledTypes = new HashSet<Class<?>>(); | Set<Class<?>> frameworkHandledTypes = new HashSet<Class<?>>(); | ||||
frameworkHandledTypes.add(Map.class); | frameworkHandledTypes.add(Map.class); | ||||
frameworkHandledTypes.add(List.class); | frameworkHandledTypes.add(List.class); | ||||
frameworkHandledTypes.add(Set.class); | frameworkHandledTypes.add(Set.class); | ||||
frameworkHandledTypes.add(Byte.class); | |||||
frameworkHandledTypes.add(Character.class); | |||||
} | } | ||||
private boolean serializationHandledByFramework(JType setterType) { | private boolean serializationHandledByFramework(JType setterType) { | ||||
// Some types are handled by the framework at the moment. See #8449 | // Some types are handled by the framework at the moment. See #8449 | ||||
// This method should be removed at some point. | // This method should be removed at some point. | ||||
if (setterType.isArray() != null) { | |||||
return true; | |||||
} | |||||
if (setterType.isPrimitive() != null) { | if (setterType.isPrimitive() != null) { | ||||
return true; | return true; | ||||
} | } |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.serialization; | |||||
import java.util.Arrays; | |||||
import java.util.Collection; | |||||
import java.util.Collections; | |||||
import java.util.HashMap; | |||||
import java.util.HashSet; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Map.Entry; | |||||
import java.util.Set; | |||||
import com.vaadin.annotations.Widgetset; | |||||
import com.vaadin.terminal.WrappedRequest; | |||||
import com.vaadin.terminal.gwt.client.Connector; | |||||
import com.vaadin.tests.components.AbstractTestRoot; | |||||
import com.vaadin.tests.util.Log; | |||||
import com.vaadin.tests.widgetset.client.ComplexTestBean; | |||||
import com.vaadin.tests.widgetset.client.SerializerTestRpc; | |||||
import com.vaadin.tests.widgetset.client.SimpleTestBean; | |||||
import com.vaadin.tests.widgetset.server.SerializerTestExtension; | |||||
@Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet") | |||||
public class SerializerTest extends AbstractTestRoot { | |||||
private Log log = new Log(40); | |||||
@Override | |||||
protected void setup(WrappedRequest request) { | |||||
final SerializerTestExtension testExtension = new SerializerTestExtension(); | |||||
addExtension(testExtension); | |||||
addComponent(log); | |||||
SerializerTestRpc rpc = testExtension | |||||
.getRpcProxy(SerializerTestRpc.class); | |||||
rpc.sendBoolean(true, Boolean.FALSE, new boolean[] { true, true, false, | |||||
true, false, false }); | |||||
rpc.sendByte((byte) 5, Byte.valueOf((byte) -12), new byte[] { 3, 1, 2 }); | |||||
rpc.sendChar('∫', Character.valueOf('å'), "aBcD".toCharArray()); | |||||
rpc.sendInt(Integer.MAX_VALUE, Integer.valueOf(0), new int[] { 5, 7 }); | |||||
rpc.sendLong(577431841358l, Long.valueOf(0), new long[] { | |||||
-57841235865l, 57 }); | |||||
rpc.sendFloat(3.14159f, Float.valueOf(Math.nextUp(1)), new float[] { | |||||
57, 0, -12 }); | |||||
rpc.sendDouble(Math.PI, Double.valueOf(-Math.E), new double[] { | |||||
Double.MAX_VALUE, Double.MIN_VALUE }); | |||||
rpc.sendString("This is a tesing string ‡"); | |||||
rpc.sendConnector(this); | |||||
rpc.sendBean( | |||||
new ComplexTestBean(new SimpleTestBean(0), | |||||
new SimpleTestBean(1), Arrays.asList( | |||||
new SimpleTestBean(3), new SimpleTestBean(4)), | |||||
5), new SimpleTestBean(6), | |||||
new SimpleTestBean[] { new SimpleTestBean(7) }); | |||||
rpc.sendNull("Not null", null); | |||||
rpc.sendNestedArray(new int[][] { { 5 }, { 7 } }, | |||||
new SimpleTestBean[][] { { new SimpleTestBean(4), | |||||
new SimpleTestBean(2) } }); | |||||
rpc.sendList(Arrays.asList(5, 8, -234), Arrays.<Connector> asList(this, | |||||
testExtension), Arrays.asList(new SimpleTestBean(234), | |||||
new SimpleTestBean(-568))); | |||||
// Disabled because of #8861 | |||||
// rpc.sendArrayList( | |||||
// Arrays.asList(new int[] { 1, 2 }, new int[] { 3, 4 }), | |||||
// Arrays.asList(new Integer[] { 5, 6 }, new Integer[] { 7, 8 }), | |||||
// Collections | |||||
// .singletonList(new SimpleTestBean[] { new SimpleTestBean( | |||||
// 7) })); | |||||
// Disabled because of #8861 | |||||
// rpc.sendListArray( | |||||
// new List[] { Arrays.asList(1, 2), Arrays.asList(3, 4) }, | |||||
// new List[] { Collections.singletonList(new SimpleTestBean(-1)) }); | |||||
rpc.sendSet(new HashSet<Integer>(Arrays.asList(4, 7, 12)), Collections | |||||
.singleton((Connector) this), new HashSet<SimpleTestBean>( | |||||
Arrays.asList(new SimpleTestBean(1), new SimpleTestBean(2)))); | |||||
rpc.sendMap(new HashMap<String, SimpleTestBean>() { | |||||
{ | |||||
put("1", new SimpleTestBean(1)); | |||||
put("2", new SimpleTestBean(2)); | |||||
} | |||||
}, new HashMap<Connector, Boolean>() { | |||||
{ | |||||
put(testExtension, true); | |||||
put(getRoot(), false); | |||||
} | |||||
}, new HashMap<Integer, Connector>() { | |||||
{ | |||||
put(5, testExtension); | |||||
put(10, getRoot()); | |||||
} | |||||
}, new HashMap<SimpleTestBean, SimpleTestBean>() { | |||||
{ | |||||
put(new SimpleTestBean(5), new SimpleTestBean(-5)); | |||||
put(new SimpleTestBean(-4), new SimpleTestBean(4)); | |||||
} | |||||
}); | |||||
rpc.sendWrappedGenerics(new HashMap<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>>() { | |||||
{ | |||||
put(Collections.singleton(new SimpleTestBean(42)), | |||||
new HashMap<Integer, List<SimpleTestBean>>() { | |||||
{ | |||||
put(1, Arrays.asList(new SimpleTestBean(1), | |||||
new SimpleTestBean(3))); | |||||
} | |||||
}); | |||||
} | |||||
}); | |||||
testExtension.registerRpc(new SerializerTestRpc() { | |||||
public void sendBoolean(boolean value, Boolean boxedValue, | |||||
boolean[] array) { | |||||
log.log("sendBoolean: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendByte(byte value, Byte boxedValue, byte[] array) { | |||||
log.log("sendByte: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendChar(char value, Character boxedValue, char[] array) { | |||||
log.log("sendChar: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendInt(int value, Integer boxedValue, int[] array) { | |||||
log.log("sendInt: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendLong(long value, Long boxedValue, long[] array) { | |||||
log.log("sendLong: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendFloat(float value, Float boxedValue, float[] array) { | |||||
log.log("sendFloat: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendDouble(double value, Double boxedValue, | |||||
double[] array) { | |||||
log.log("sendDouble: " + value + ", " + boxedValue + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendString(String value) { | |||||
log.log("sendString: " + value); | |||||
} | |||||
public void sendConnector(Connector connector) { | |||||
log.log("sendConnector: " + connector.getClass().getName()); | |||||
} | |||||
public void sendBean(ComplexTestBean complexBean, | |||||
SimpleTestBean simpleBean, SimpleTestBean[] array) { | |||||
log.log("sendBean: " + complexBean + ", " + simpleBean + ", " | |||||
+ Arrays.toString(array)); | |||||
} | |||||
public void sendNull(String value1, String value2) { | |||||
log.log("sendNull: " + value1 + ", " + value2); | |||||
} | |||||
public void sendNestedArray(int[][] nestedIntArray, | |||||
SimpleTestBean[][] nestedBeanArray) { | |||||
log.log("sendNestedArray: " | |||||
+ Arrays.deepToString(nestedIntArray) + ", " | |||||
+ Arrays.deepToString(nestedBeanArray)); | |||||
} | |||||
public void sendList(List<Integer> intList, | |||||
List<Connector> connectorList, List<SimpleTestBean> beanList) { | |||||
log.log("sendList: " + intList + ", " | |||||
+ connectorCollectionToString(connectorList) + ", " | |||||
+ beanList); | |||||
} | |||||
private String connectorCollectionToString( | |||||
Collection<Connector> collection) { | |||||
StringBuilder sb = new StringBuilder(); | |||||
for (Connector connector : collection) { | |||||
if (sb.length() != 0) { | |||||
sb.append(", "); | |||||
} | |||||
sb.append(connector.getClass()); | |||||
} | |||||
String string = sb.toString(); | |||||
return string; | |||||
} | |||||
public void sendArrayList(List<int[]> primitiveArrayList, | |||||
List<Integer[]> objectArrayList, | |||||
List<SimpleTestBean[]> beanArrayList) { | |||||
log.log("sendArrayList: " + primitiveArrayList + ", " | |||||
+ objectArrayList + ", " + beanArrayList); | |||||
} | |||||
public void sendListArray(List<Integer>[] objectListArray, | |||||
List<SimpleTestBean>[] beanListArray) { | |||||
log.log("sendArrayList: " + Arrays.toString(objectListArray) | |||||
+ ", " + Arrays.toString(beanListArray)); | |||||
} | |||||
public void sendSet(Set<Integer> intSet, | |||||
Set<Connector> connectorSet, Set<SimpleTestBean> beanSet) { | |||||
log.log("sendSet: " + intSet + ", " | |||||
+ connectorCollectionToString(connectorSet) + ", " | |||||
+ beanSet); | |||||
} | |||||
public void sendMap(Map<String, SimpleTestBean> stringMap, | |||||
Map<Connector, Boolean> connectorMap, | |||||
Map<Integer, Connector> intMap, | |||||
Map<SimpleTestBean, SimpleTestBean> beanMap) { | |||||
StringBuilder sb = new StringBuilder(); | |||||
for (Entry<Connector, Boolean> entry : connectorMap.entrySet()) { | |||||
if (sb.length() == 0) { | |||||
sb.append('['); | |||||
} else { | |||||
sb.append(", "); | |||||
} | |||||
sb.append(entry.getKey().getClass().getName()); | |||||
sb.append('='); | |||||
sb.append(entry.getValue()); | |||||
} | |||||
sb.append(']'); | |||||
String connectorMapString = sb.toString(); | |||||
sb = new StringBuilder(); | |||||
for (Entry<Integer, Connector> entry : intMap.entrySet()) { | |||||
if (sb.length() == 0) { | |||||
sb.append('['); | |||||
} else { | |||||
sb.append(", "); | |||||
} | |||||
sb.append(entry.getKey()); | |||||
sb.append('='); | |||||
sb.append(entry.getValue().getClass().getName()); | |||||
} | |||||
sb.append(']'); | |||||
String intMapString = sb.toString(); | |||||
log.log("sendMap: " + stringMap + ", " + connectorMapString | |||||
+ ", " + intMapString + ", " + beanMap); | |||||
} | |||||
public void sendWrappedGenerics( | |||||
Map<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>> generics) { | |||||
log.log("sendWrappedGenerics: " + generics.toString()); | |||||
} | |||||
}); | |||||
} | |||||
@Override | |||||
protected String getTestDescription() { | |||||
return "Test for lots of different cases of encoding and decoding variuos data types"; | |||||
} | |||||
@Override | |||||
protected Integer getTicketNumber() { | |||||
return Integer.valueOf(8655); | |||||
} | |||||
} |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.widgetset.client; | |||||
import java.util.List; | |||||
import com.vaadin.terminal.gwt.client.communication.SharedState; | |||||
@SuppressWarnings("javadoc") | |||||
public class ComplexTestBean extends SharedState { | |||||
private SimpleTestBean innerBean1; | |||||
private SimpleTestBean innerBean2; | |||||
private List<SimpleTestBean> innerBeanCollection; | |||||
private int privimite; | |||||
public ComplexTestBean() { | |||||
// Default | |||||
} | |||||
public ComplexTestBean(SimpleTestBean innerBean1, | |||||
SimpleTestBean innerBean2, | |||||
List<SimpleTestBean> innerBeanCollection, int privimite) { | |||||
this.innerBean1 = innerBean1; | |||||
this.innerBean2 = innerBean2; | |||||
this.innerBeanCollection = innerBeanCollection; | |||||
this.privimite = privimite; | |||||
} | |||||
public SimpleTestBean getInnerBean1() { | |||||
return innerBean1; | |||||
} | |||||
public void setInnerBean1(SimpleTestBean innerBean) { | |||||
innerBean1 = innerBean; | |||||
} | |||||
public SimpleTestBean getInnerBean2() { | |||||
return innerBean2; | |||||
} | |||||
public void setInnerBean2(SimpleTestBean innerBean2) { | |||||
this.innerBean2 = innerBean2; | |||||
} | |||||
public List<SimpleTestBean> getInnerBeanCollection() { | |||||
return innerBeanCollection; | |||||
} | |||||
public void setInnerBeanCollection(List<SimpleTestBean> innerBeanCollection) { | |||||
this.innerBeanCollection = innerBeanCollection; | |||||
} | |||||
public int getPrivimite() { | |||||
return privimite; | |||||
} | |||||
public void setPrivimite(int privimite) { | |||||
this.privimite = privimite; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "ComplexTestBean [innerBean1=" + innerBean1 + ", innerBean2=" | |||||
+ innerBean2 + ", innerBeanCollection=" + innerBeanCollection | |||||
+ ", privimite=" + privimite + "]"; | |||||
} | |||||
} |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.widgetset.client; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.Collections; | |||||
import java.util.HashMap; | |||||
import java.util.HashSet; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Map.Entry; | |||||
import java.util.Set; | |||||
import com.vaadin.terminal.gwt.client.Connector; | |||||
import com.vaadin.terminal.gwt.client.communication.RpcProxy; | |||||
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; | |||||
import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; | |||||
import com.vaadin.terminal.gwt.client.ui.Connect; | |||||
import com.vaadin.tests.widgetset.server.SerializerTestExtension; | |||||
@Connect(SerializerTestExtension.class) | |||||
public class SerializerTestConnector extends AbstractExtensionConnector { | |||||
private SerializerTestRpc rpc = RpcProxy.create(SerializerTestRpc.class, | |||||
this); | |||||
public SerializerTestConnector() { | |||||
registerRpc(SerializerTestRpc.class, new SerializerTestRpc() { | |||||
public void sendWrappedGenerics( | |||||
Map<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>> generics) { | |||||
Map<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>> updated = new HashMap<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>>(); | |||||
SimpleTestBean firstValue = generics.values().iterator().next() | |||||
.get(Integer.valueOf(1)).get(0); | |||||
Set<SimpleTestBean> key = new HashSet<SimpleTestBean>(Arrays | |||||
.asList(firstValue)); | |||||
Map<Integer, List<SimpleTestBean>> value = new HashMap<Integer, List<SimpleTestBean>>(); | |||||
Set<SimpleTestBean> firstKeyValue = generics.keySet() | |||||
.iterator().next(); | |||||
value.put(Integer.valueOf(1), new ArrayList<SimpleTestBean>( | |||||
firstKeyValue)); | |||||
updated.put(key, value); | |||||
rpc.sendWrappedGenerics(updated); | |||||
} | |||||
public void sendString(String value) { | |||||
char[] chars = value.toCharArray(); | |||||
Arrays.sort(chars); | |||||
rpc.sendString(new String(chars)); | |||||
} | |||||
public void sendSet(Set<Integer> intSet, | |||||
Set<Connector> connectorSet, Set<SimpleTestBean> beanSet) { | |||||
beanSet.iterator().next().setValue(intSet.size()); | |||||
Set<Integer> updatedIntSet = new HashSet<Integer>(); | |||||
for (Integer integer : intSet) { | |||||
updatedIntSet.add(Integer.valueOf(-integer.intValue())); | |||||
} | |||||
rpc.sendSet(updatedIntSet, | |||||
Collections.singleton(getRootConnector()), beanSet); | |||||
} | |||||
public void sendNestedArray(int[][] nestedIntArray, | |||||
SimpleTestBean[][] nestedBeanArray) { | |||||
rpc.sendNestedArray(new int[][] { { nestedIntArray[1][0], | |||||
nestedIntArray[0][0] } }, new SimpleTestBean[][] { | |||||
{ nestedBeanArray[0][1] }, { nestedBeanArray[0][0] } }); | |||||
} | |||||
public void sendMap(Map<String, SimpleTestBean> stringMap, | |||||
Map<Connector, Boolean> connectorMap, | |||||
Map<Integer, Connector> intMap, | |||||
Map<SimpleTestBean, SimpleTestBean> beanMap) { | |||||
Map<SimpleTestBean, SimpleTestBean> updatedBeanMap = new HashMap<SimpleTestBean, SimpleTestBean>(); | |||||
for (Entry<SimpleTestBean, SimpleTestBean> entry : beanMap | |||||
.entrySet()) { | |||||
updatedBeanMap.put(entry.getValue(), entry.getKey()); | |||||
} | |||||
rpc.sendMap(Collections.singletonMap("a", stringMap.get("b")), | |||||
Collections.singletonMap(getThisConnector(), | |||||
connectorMap.get(getRootConnector())), | |||||
Collections.singletonMap( | |||||
Integer.valueOf(stringMap.size()), | |||||
getThisConnector()), updatedBeanMap); | |||||
} | |||||
public void sendLong(long value, Long boxedValue, long[] array) { | |||||
rpc.sendLong(array[0], Long.valueOf(value), new long[] { | |||||
array[1], boxedValue.longValue() }); | |||||
} | |||||
public void sendList(List<Integer> intList, | |||||
List<Connector> connectorList, List<SimpleTestBean> beanList) { | |||||
Collections.sort(intList); | |||||
Collections.reverse(beanList); | |||||
rpc.sendList(intList, | |||||
Arrays.asList(getThisConnector(), getRootConnector()), | |||||
beanList); | |||||
} | |||||
public void sendInt(int value, Integer boxedValue, int[] array) { | |||||
rpc.sendInt(array.length, Integer.valueOf(array[0]), new int[] { | |||||
value, boxedValue.intValue() }); | |||||
} | |||||
public void sendFloat(float value, Float boxedValue, float[] array) { | |||||
Arrays.sort(array); | |||||
rpc.sendFloat(boxedValue.floatValue(), Float.valueOf(value), | |||||
array); | |||||
} | |||||
public void sendDouble(double value, Double boxedValue, | |||||
double[] array) { | |||||
rpc.sendDouble(value + boxedValue.doubleValue(), | |||||
Double.valueOf(value - boxedValue.doubleValue()), | |||||
new double[] { array.length, array[0], array[1] }); | |||||
} | |||||
public void sendConnector(Connector connector) { | |||||
rpc.sendConnector(getThisConnector()); | |||||
} | |||||
public void sendChar(char value, Character boxedValue, char[] array) { | |||||
rpc.sendChar(Character.toUpperCase(boxedValue.charValue()), | |||||
Character.valueOf(value), new String(array) | |||||
.toLowerCase().toCharArray()); | |||||
} | |||||
public void sendByte(byte value, Byte boxedValue, byte[] array) { | |||||
// There will most certainly be a bug that is not discovered | |||||
// because this particular method doesn't do anything with it's | |||||
// values... | |||||
rpc.sendByte(value, boxedValue, array); | |||||
} | |||||
public void sendBoolean(boolean value, Boolean boxedValue, | |||||
boolean[] array) { | |||||
boolean[] inverseArray = new boolean[array.length]; | |||||
for (int i = 0; i < array.length; i++) { | |||||
inverseArray[i] = !array[i]; | |||||
} | |||||
rpc.sendBoolean(boxedValue == Boolean.TRUE, | |||||
Boolean.valueOf(!value), inverseArray); | |||||
} | |||||
public void sendBean(ComplexTestBean complexBean, | |||||
SimpleTestBean simpleBean, SimpleTestBean[] array) { | |||||
SimpleTestBean updatedSimpleBean = new SimpleTestBean(); | |||||
updatedSimpleBean.setValue(complexBean.getInnerBean1() | |||||
.getValue()); | |||||
ComplexTestBean updatedComplexBean = new ComplexTestBean(); | |||||
updatedComplexBean.setInnerBean1(complexBean.getInnerBean2()); | |||||
updatedComplexBean.setInnerBean2(complexBean | |||||
.getInnerBeanCollection().get(0)); | |||||
updatedComplexBean.setInnerBeanCollection(Arrays.asList( | |||||
simpleBean, updatedSimpleBean)); | |||||
updatedComplexBean.setPrivimite(complexBean.getPrivimite() + 1); | |||||
ArrayList<SimpleTestBean> arrayList = new ArrayList<SimpleTestBean>( | |||||
Arrays.asList(array)); | |||||
Collections.reverse(arrayList); | |||||
rpc.sendBean(updatedComplexBean, updatedSimpleBean, | |||||
arrayList.toArray(new SimpleTestBean[array.length])); | |||||
} | |||||
public void sendArrayList(List<int[]> primitiveArrayList, | |||||
List<Integer[]> objectArrayList, | |||||
List<SimpleTestBean[]> beanArrayList) { | |||||
Collections.reverse(beanArrayList); | |||||
List<Integer[]> updatedObjectArrayList = new ArrayList<Integer[]>(); | |||||
for (int[] array : primitiveArrayList) { | |||||
updatedObjectArrayList.add(new Integer[] { | |||||
Integer.valueOf(array.length), | |||||
Integer.valueOf(array[0]) }); | |||||
} | |||||
rpc.sendArrayList(Arrays.asList( | |||||
new int[] { primitiveArrayList.size() }, | |||||
new int[] { objectArrayList.get(0).length }), | |||||
updatedObjectArrayList, beanArrayList); | |||||
} | |||||
public void sendNull(String value1, String value2) { | |||||
rpc.sendNull(value2, value1); | |||||
} | |||||
public void sendListArray(List<Integer>[] objectListArray, | |||||
List<SimpleTestBean>[] beanListArray) { | |||||
rpc.sendListArray(new List[] { objectListArray[1], | |||||
objectListArray[0] }, new List[] { Collections | |||||
.singletonList(beanListArray[0].get(0)) }); | |||||
} | |||||
}); | |||||
} | |||||
private Connector getRootConnector() { | |||||
return getConnection().getRootConnector(); | |||||
} | |||||
private Connector getThisConnector() { | |||||
// Cast to Connector for use in e.g. Collections.singleton() to get a | |||||
// Set<Connector> | |||||
return this; | |||||
} | |||||
@Override | |||||
public ComplexTestBean getState() { | |||||
return (ComplexTestBean) super.getState(); | |||||
} | |||||
@Override | |||||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | |||||
// TODO do something clever | |||||
} | |||||
} |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.widgetset.client; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Set; | |||||
import com.vaadin.terminal.gwt.client.Connector; | |||||
import com.vaadin.terminal.gwt.client.communication.ClientRpc; | |||||
import com.vaadin.terminal.gwt.client.communication.ServerRpc; | |||||
@SuppressWarnings("javadoc") | |||||
public interface SerializerTestRpc extends ServerRpc, ClientRpc { | |||||
public void sendBoolean(boolean value, Boolean boxedValue, boolean[] array); | |||||
public void sendByte(byte value, Byte boxedValue, byte[] array); | |||||
public void sendChar(char value, Character boxedValue, char[] array); | |||||
public void sendInt(int value, Integer boxedValue, int[] array); | |||||
public void sendLong(long value, Long boxedValue, long[] array); | |||||
public void sendFloat(float value, Float boxedValue, float[] array); | |||||
public void sendDouble(double value, Double boxedValue, double[] array); | |||||
public void sendString(String value); | |||||
public void sendConnector(Connector connector); | |||||
public void sendBean(ComplexTestBean complexBean, | |||||
SimpleTestBean simpleBean, SimpleTestBean[] array); | |||||
public void sendNull(String value1, String value2); | |||||
public void sendNestedArray(int[][] nestedIntArray, | |||||
SimpleTestBean[][] nestedBeanArray); | |||||
public void sendList(List<Integer> intList, List<Connector> connectorList, | |||||
List<SimpleTestBean> beanList); | |||||
public void sendArrayList(List<int[]> primitiveArrayList, | |||||
List<Integer[]> objectArrayList, | |||||
List<SimpleTestBean[]> beanArrayList); | |||||
public void sendListArray(List<Integer>[] objectListArray, | |||||
List<SimpleTestBean>[] beanListArray); | |||||
public void sendSet(Set<Integer> intSet, Set<Connector> connectorSet, | |||||
Set<SimpleTestBean> beanSet); | |||||
public void sendMap(Map<String, SimpleTestBean> stringMap, | |||||
Map<Connector, Boolean> connectorMap, | |||||
Map<Integer, Connector> intMap, | |||||
Map<SimpleTestBean, SimpleTestBean> beanMap); | |||||
public void sendWrappedGenerics( | |||||
Map<Set<SimpleTestBean>, Map<Integer, List<SimpleTestBean>>> generics); | |||||
} |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.widgetset.client; | |||||
import java.io.Serializable; | |||||
public class SimpleTestBean implements Serializable { | |||||
private int value; | |||||
public SimpleTestBean() { | |||||
this(0); | |||||
} | |||||
public SimpleTestBean(int value) { | |||||
this.value = value; | |||||
} | |||||
public int getValue() { | |||||
return value; | |||||
} | |||||
public void setValue(int value) { | |||||
this.value = value; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "SimpleTestBean(" + value + ")"; | |||||
} | |||||
@Override | |||||
public int hashCode() { | |||||
// Implement hash code to get consistent HashSet.toString | |||||
return value; | |||||
} | |||||
} |
/* | |||||
@VaadinApache2LicenseForJavaFiles@ | |||||
*/ | |||||
package com.vaadin.tests.widgetset.server; | |||||
import com.vaadin.terminal.AbstractExtension; | |||||
import com.vaadin.tests.widgetset.client.ComplexTestBean; | |||||
import com.vaadin.tests.widgetset.client.SerializerTestRpc; | |||||
public class SerializerTestExtension extends AbstractExtension { | |||||
@Override | |||||
public ComplexTestBean getState() { | |||||
return (ComplexTestBean) super.getState(); | |||||
} | |||||
public void registerRpc(SerializerTestRpc rpc) { | |||||
super.registerRpc(rpc); | |||||
} | |||||
} |