Przeglądaj źródła

#8515 Additional fix for sets, and lists from client to server

tags/7.0.0.alpha2
Artur Signell 12 lat temu
rodzic
commit
cf925d995b

+ 15
- 0
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java Wyświetl plik

@@ -6,9 +6,11 @@ package com.vaadin.terminal.gwt.client.communication;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONArray;
@@ -63,6 +65,8 @@ public class JsonDecoder {
val = decodeMap((JSONObject) value, idMapper, connection);
} else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
val = decodeList((JSONArray) value, idMapper, connection);
} else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
val = decodeSet((JSONArray) value, idMapper, connection);
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
val = decodeStringArray((JSONArray) value);
} else if (JsonEncoder.VTYPE_STRING.equals(variableType)) {
@@ -135,4 +139,15 @@ public class JsonDecoder {
}
return tokens;
}

private static Set<Object> decodeSet(JSONArray jsonArray,
ConnectorMap idMapper, ApplicationConnection connection) {
Set<Object> tokens = new HashSet<Object>();
for (int i = 0; i < jsonArray.size(); ++i) {
// each entry always has two elements: type and value
JSONArray entryArray = (JSONArray) jsonArray.get(i);
tokens.add(decodeValue(entryArray, idMapper, connection));
}
return tokens;
}
}

+ 38
- 7
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java Wyświetl plik

@@ -4,8 +4,10 @@

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

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
@@ -41,6 +43,7 @@ public class JsonEncoder {
public static final String VTYPE_STRINGARRAY = "S";
public static final String VTYPE_MAP = "m";
public static final String VTYPE_LIST = "L";
public static final String VTYPE_SET = "q";
public static final String VTYPE_NULL = "n";

/**
@@ -72,13 +75,7 @@ public class JsonEncoder {
return combineTypeAndValue(VTYPE_BOOLEAN,
JSONBoolean.getInstance((Boolean) value));
} else if (value instanceof Object[]) {
Object[] array = (Object[]) value;
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < array.length; ++i) {
// TODO handle object graph loops?
jsonArray.set(i, encode(array[i], connectorMap, connection));
}
return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
return encodeObjectArray((Object[]) value, connectorMap, connection);
} else if (value instanceof Map) {
Map<String, Object> map = (Map<String, Object>) value;
JSONObject jsonMap = new JSONObject();
@@ -92,6 +89,9 @@ public class JsonEncoder {
Connector connector = (Connector) value;
return combineTypeAndValue(VTYPE_CONNECTOR, new JSONString(
connector.getConnectorId()));
} else if (value instanceof Collection) {
return encodeCollection((Collection) value, connectorMap,
connection);
} else {
String transportType = getTransportType(value);
if (transportType != null) {
@@ -111,6 +111,35 @@ public class JsonEncoder {
}
}

private static JSONValue encodeObjectArray(Object[] array,
ConnectorMap connectorMap, ApplicationConnection connection) {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < array.length; ++i) {
// TODO handle object graph loops?
jsonArray.set(i, encode(array[i], connectorMap, connection));
}
return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
}

private static JSONValue encodeCollection(Collection collection,
ConnectorMap connectorMap, ApplicationConnection connection) {
JSONArray jsonArray = new JSONArray();
int idx = 0;
for (Object o : collection) {
JSONValue encodedObject = encode(o, connectorMap, connection);
jsonArray.set(idx++, encodedObject);
}
if (collection instanceof Set) {
return combineTypeAndValue(VTYPE_SET, jsonArray);
} else if (collection instanceof List) {
return combineTypeAndValue(VTYPE_LIST, jsonArray);
} else {
throw new RuntimeException("Unsupport collection type: "
+ collection.getClass().getName());
}

}

private static JSONValue combineTypeAndValue(String type, JSONValue value) {
JSONArray outerArray = new JSONArray();
outerArray.set(0, new JSONString(type));
@@ -137,6 +166,8 @@ public class JsonEncoder {
return VTYPE_LONG;
} else if (value instanceof List) {
return VTYPE_LIST;
} else if (value instanceof Set) {
return VTYPE_SET;
} else if (value instanceof Enum) {
return VTYPE_STRING; // transported as string representation
} else if (value instanceof String[]) {

+ 63
- 21
src/com/vaadin/terminal/gwt/server/JsonCodec.java Wyświetl plik

@@ -11,10 +11,13 @@ import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.vaadin.Application;
import com.vaadin.external.json.JSONArray;
@@ -38,16 +41,22 @@ public class JsonCodec implements Serializable {
registerType(String.class, JsonEncoder.VTYPE_STRING);
registerType(Connector.class, JsonEncoder.VTYPE_CONNECTOR);
registerType(Boolean.class, JsonEncoder.VTYPE_BOOLEAN);
registerType(boolean.class, JsonEncoder.VTYPE_BOOLEAN);
registerType(Integer.class, JsonEncoder.VTYPE_INTEGER);
registerType(int.class, JsonEncoder.VTYPE_INTEGER);
registerType(Float.class, JsonEncoder.VTYPE_FLOAT);
registerType(float.class, JsonEncoder.VTYPE_FLOAT);
registerType(Double.class, JsonEncoder.VTYPE_DOUBLE);
registerType(double.class, JsonEncoder.VTYPE_FLOAT);
registerType(Long.class, JsonEncoder.VTYPE_LONG);
registerType(long.class, JsonEncoder.VTYPE_LONG);
// transported as string representation
registerType(Enum.class, JsonEncoder.VTYPE_STRING);
registerType(String[].class, JsonEncoder.VTYPE_STRINGARRAY);
registerType(Object[].class, JsonEncoder.VTYPE_ARRAY);
registerType(Map.class, JsonEncoder.VTYPE_MAP);
registerType(List.class, JsonEncoder.VTYPE_LIST);
registerType(Set.class, JsonEncoder.VTYPE_SET);
}

private static void registerType(Class<?> type, String transportType) {
@@ -80,6 +89,8 @@ public class JsonCodec implements Serializable {
val = decodeArray((JSONArray) value, application);
} else if (JsonEncoder.VTYPE_LIST.equals(variableType)) {
val = decodeList((JSONArray) value, application);
} else if (JsonEncoder.VTYPE_SET.equals(variableType)) {
val = decodeSet((JSONArray) value, application);
} else if (JsonEncoder.VTYPE_MAP.equals(variableType)) {
val = decodeMap((JSONObject) value, application);
} else if (JsonEncoder.VTYPE_STRINGARRAY.equals(variableType)) {
@@ -141,8 +152,8 @@ public class JsonCodec implements Serializable {
return list.toArray(new Object[list.size()]);
}

private static List decodeList(JSONArray jsonArray, Application application)
throws JSONException {
private static List<Object> decodeList(JSONArray jsonArray,
Application application) throws JSONException {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < jsonArray.length(); ++i) {
// each entry always has two elements: type and value
@@ -152,6 +163,13 @@ public class JsonCodec implements Serializable {
return list;
}

private static Set<Object> decodeSet(JSONArray jsonArray,
Application application) throws JSONException {
HashSet<Object> set = new HashSet<Object>();
set.addAll(decodeList(jsonArray, application));
return set;
}

/**
* Encode a value to a JSON representation for transport from the server to
* the client.
@@ -174,7 +192,14 @@ public class JsonCodec implements Serializable {

if (null == value) {
return combineTypeAndValue(JsonEncoder.VTYPE_NULL, JSONObject.NULL);
} else if (value instanceof String[]) {
}

if (valueType == null) {
valueType = value.getClass();
}

String transportType = getTransportType(valueType);
if (value instanceof String[]) {
String[] array = (String[]) value;
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < array.length; ++i) {
@@ -186,11 +211,16 @@ public class JsonCodec implements Serializable {
} else if (value instanceof Boolean) {
return combineTypeAndValue(JsonEncoder.VTYPE_BOOLEAN, value);
} else if (value instanceof Number) {
return combineTypeAndValue(getTransportType(value), value);
} else if (value instanceof List) {
List list = (List) value;
JSONArray jsonArray = encodeList(list, application);
return combineTypeAndValue(JsonEncoder.VTYPE_LIST, jsonArray);
return combineTypeAndValue(transportType, value);
} else if (value instanceof Collection) {
if (transportType == null) {
throw new RuntimeException(
"Unable to serialize unsupported type: " + valueType);
}
Collection<?> collection = (Collection<?>) value;
JSONArray jsonArray = encodeCollection(collection, application);

return combineTypeAndValue(transportType, jsonArray);
} else if (value instanceof Object[]) {
Object[] array = (Object[]) value;
JSONArray jsonArray = encodeArrayContents(array, application);
@@ -203,16 +233,11 @@ public class JsonCodec implements Serializable {
Connector connector = (Connector) value;
return combineTypeAndValue(JsonEncoder.VTYPE_CONNECTOR,
connector.getConnectorId());
} else if (getTransportType(value) != null) {
return combineTypeAndValue(getTransportType(value),
String.valueOf(value));
} else if (transportType != null) {
return combineTypeAndValue(transportType, String.valueOf(value));
} else {
// Any object that we do not know how to encode we encode by looping
// through fields
if (valueType == null) {
valueType = value.getClass();
}

return combineTypeAndValue(valueType.getCanonicalName(),
encodeObject(value, application));
}
@@ -290,10 +315,10 @@ public class JsonCodec implements Serializable {
return jsonArray;
}

private static JSONArray encodeList(List list, Application application)
throws JSONException {
private static JSONArray encodeCollection(Collection collection,
Application application) throws JSONException {
JSONArray jsonArray = new JSONArray();
for (Object o : list) {
for (Object o : collection) {
// TODO handle object graph loops?
jsonArray.put(encode(o, application));
}
@@ -312,6 +337,10 @@ public class JsonCodec implements Serializable {
}

private static JSONArray combineTypeAndValue(String type, Object value) {
if (type == null) {
throw new RuntimeException("Type for value " + value
+ " cannot be null!");
}
JSONArray outerArray = new JSONArray();
outerArray.put(type);
outerArray.put(value);
@@ -326,12 +355,25 @@ public class JsonCodec implements Serializable {
* @return
* @throws JSONException
*/
private static String getTransportType(Object value) throws JSONException {
private static String getTransportType(Object value) {
if (null == value) {
return JsonEncoder.VTYPE_NULL;
}
String transportType = typeToTransportType.get(value.getClass());
return transportType;
return getTransportType(value.getClass());
}

/**
* Gets the transport type for the given class. Returns null if no transport
* type can be found.
*
* @param valueType
* The type that should be transported
* @return
* @throws JSONException
*/
private static String getTransportType(Class<?> valueType) {
return typeToTransportType.get(valueType);

}

}

+ 3
- 2
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java Wyświetl plik

@@ -230,8 +230,9 @@ public class SerializerGenerator extends Generator {

List<JMethod> setterMethods = new ArrayList<JMethod>();

while (!beanType.getQualifiedSourceName()
.equals(Object.class.getName())) {
while (beanType != null
&& !beanType.getQualifiedSourceName().equals(
Object.class.getName())) {
for (JMethod method : beanType.getMethods()) {
// Process all setters that have corresponding fields
if (!method.isPublic() || method.isStatic()

+ 13
- 1
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java Wyświetl plik

@@ -7,6 +7,7 @@ package com.vaadin.terminal.gwt.widgetsetutils;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@@ -199,7 +200,16 @@ public class SerializerMapGenerator extends Generator {
continue;
}
for (JType type : method.getParameterTypes()) {
types.add(type.isClass());
JClassType t = type.isClass();
JClassType interfaceType = type.isInterface();
if (t != null) {
types.add(t);
} else if (interfaceType != null) {
types.add(interfaceType);
} else {
System.err.println("Unknown method parameter type: "
+ type.getQualifiedSourceName());
}
}
}
}
@@ -242,6 +252,8 @@ public class SerializerMapGenerator extends Generator {
frameworkHandledTypes.add(String[].class);
frameworkHandledTypes.add(Object[].class);
frameworkHandledTypes.add(Map.class);
frameworkHandledTypes.add(List.class);
frameworkHandledTypes.add(Set.class);

}


Ładowanie…
Anuluj
Zapisz