]> source.dussan.org Git - vaadin-framework.git/commitdiff
Drop explicit type info from client -> server communication (#8879)
authorLeif Åstrand <leif@vaadin.com>
Wed, 30 May 2012 14:35:22 +0000 (17:35 +0300)
committerLeif Åstrand <leif@vaadin.com>
Wed, 6 Jun 2012 10:33:40 +0000 (13:33 +0300)
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
src/com/vaadin/terminal/gwt/server/JsonCodec.java

index 20ed319253aa68a40ab0a8cf2050ee83857e0174..541dc631c6b48015bd533b8fe0832dfae8abae7d 100644 (file)
@@ -46,12 +46,6 @@ public class JsonEncoder {
     public static final String VTYPE_SET = "q";
     public static final String VTYPE_NULL = "n";
 
-    /**
-     * Temporary hack to get variable changes decoded as internal types in
-     * JsonCodec.
-     */
-    public static final String VTYPE_UIDL_VALUE = "v";
-
     /**
      * Encode a value to a JSON representation for transport from the client to
      * the server.
@@ -67,20 +61,18 @@ public class JsonEncoder {
             boolean restrictToInternalTypes, ConnectorMap connectorMap,
             ApplicationConnection connection) {
         if (null == value) {
-            return combineTypeAndValue(VTYPE_NULL, JSONNull.getInstance());
+            return JSONNull.getInstance();
         } else if (value instanceof String[]) {
             String[] array = (String[]) value;
             JSONArray jsonArray = new JSONArray();
             for (int i = 0; i < array.length; ++i) {
                 jsonArray.set(i, new JSONString(array[i]));
             }
-            return combineTypeAndValue(VTYPE_STRINGARRAY, jsonArray);
+            return jsonArray;
         } else if (value instanceof String) {
-            return combineTypeAndValue(VTYPE_STRING, new JSONString(
-                    (String) value));
+            return new JSONString((String) value);
         } else if (value instanceof Boolean) {
-            return combineTypeAndValue(VTYPE_BOOLEAN,
-                    JSONBoolean.getInstance((Boolean) value));
+            return JSONBoolean.getInstance((Boolean) value);
         } else if (value instanceof Object[]) {
             return encodeObjectArray((Object[]) value, restrictToInternalTypes,
                     connectorMap, connection);
@@ -99,8 +91,7 @@ public class JsonEncoder {
                     connectorMap, connection);
         } else if (value instanceof Connector) {
             Connector connector = (Connector) value;
-            return combineTypeAndValue(VTYPE_CONNECTOR, new JSONString(
-                    connector.getConnectorId()));
+            return new JSONString(connector.getConnectorId());
         } else if (value instanceof Collection) {
             return encodeCollection((Collection) value,
                     restrictToInternalTypes, connectorMap, connection);
@@ -110,8 +101,7 @@ public class JsonEncoder {
         } else {
             String transportType = getTransportType(value);
             if (transportType != null) {
-                return combineTypeAndValue(transportType,
-                        new JSONString(String.valueOf(value)));
+                return new JSONString(String.valueOf(value));
             } else {
                 // Try to find a generated serializer object, class name is the
                 // type
@@ -120,18 +110,20 @@ public class JsonEncoder {
                         .getSerializer(transportType);
 
                 // TODO handle case with no serializer found
-                return combineTypeAndValue(transportType,
-                        serializer.serialize(value, connectorMap, connection));
+                return serializer.serialize(value, connectorMap, connection);
             }
         }
     }
 
-    private static JSONValue encodeVariableChange(UidlValue value,
+    private static JSONValue encodeVariableChange(UidlValue uidlValue,
             ConnectorMap connectorMap, ApplicationConnection connection) {
-        JSONArray encodedValue = encode(value.getValue(), true, connectorMap,
-                connection).isArray();
+        Object value = uidlValue.getValue();
 
-        return combineTypeAndValue(VTYPE_UIDL_VALUE, encodedValue);
+        JSONArray jsonArray = new JSONArray();
+        jsonArray.set(0, new JSONString(getTransportType(value)));
+        jsonArray.set(1, encode(value, true, connectorMap, connection));
+
+        return jsonArray;
     }
 
     private static JSONValue encodeMap(Map<Object, Object> map,
@@ -155,13 +147,12 @@ public class JsonEncoder {
                     connectorMap, connection);
             jsonMap.put(encodedKey.toString(), encodedValue);
         }
-        return combineTypeAndValue(VTYPE_MAP, jsonMap);
+        return jsonMap;
     }
 
     private static JSONValue encodeEnum(Enum e, ConnectorMap connectorMap,
             ApplicationConnection connection) {
-        return combineTypeAndValue(e.getClass().getName(),
-                new JSONString(e.toString()));
+        return new JSONString(e.toString());
     }
 
     private static JSONValue encodeObjectArray(Object[] array,
@@ -179,7 +170,7 @@ public class JsonEncoder {
                     encode(value, restrictToInternalTypes, connectorMap,
                             connection));
         }
-        return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
+        return jsonArray;
     }
 
     private static JSONValue encodeCollection(Collection collection,
@@ -193,9 +184,9 @@ public class JsonEncoder {
             jsonArray.set(idx++, encodedObject);
         }
         if (collection instanceof Set) {
-            return combineTypeAndValue(VTYPE_SET, jsonArray);
+            return jsonArray;
         } else if (collection instanceof List) {
-            return combineTypeAndValue(VTYPE_LIST, jsonArray);
+            return jsonArray;
         } else {
             throw new RuntimeException("Unsupport collection type: "
                     + collection.getClass().getName());
@@ -203,13 +194,6 @@ public class JsonEncoder {
 
     }
 
-    private static JSONValue combineTypeAndValue(String type, JSONValue value) {
-        JSONArray outerArray = new JSONArray();
-        outerArray.set(0, new JSONString(type));
-        outerArray.set(1, value);
-        return outerArray;
-    }
-
     /**
      * Returns the transport type for the given value. Only returns a transport
      * type for internally handled values.
index 11e86b99fcc68f9eb782ad673a8fd6c450f0fa0a..b32525a7033ef8e936847a1777ac3518adaac373 100644 (file)
@@ -1628,12 +1628,9 @@ public abstract class AbstractCommunicationManager implements Serializable {
                     "Invalid parameters in legacy change variables call. Expected 2, was "
                             + parametersJson.length());
         }
-        String variableName = (String) JsonCodec
-                .decodeInternalType(String.class, true,
-                        parametersJson.getJSONArray(0), application);
+        String variableName = parametersJson.getString(0);
         UidlValue uidlValue = (UidlValue) JsonCodec.decodeInternalType(
-                UidlValue.class, true, parametersJson.getJSONArray(1),
-                application);
+                UidlValue.class, true, parametersJson.get(1), application);
 
         Object value = uidlValue.getValue();
 
@@ -1658,10 +1655,10 @@ public abstract class AbstractCommunicationManager implements Serializable {
                 .getGenericParameterTypes();
 
         for (int j = 0; j < parametersJson.length(); ++j) {
-            JSONArray parameterJson = parametersJson.getJSONArray(j);
+            Object parameterValue = parametersJson.get(j);
             Type parameterType = declaredRpcMethodParameterTypes[j];
             parameters[j] = JsonCodec.decodeInternalOrCustomType(parameterType,
-                    parameterJson, application);
+                    parameterValue, application);
         }
         invocation.setParameters(parameters);
         return invocation;
index a7515c7135c1c02cc1688601c3d294e1f7ea8603..b853c90a3bc1844a563260dff3662185a1d2a472 100644 (file)
@@ -13,7 +13,6 @@ import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -26,6 +25,7 @@ import com.vaadin.Application;
 import com.vaadin.external.json.JSONArray;
 import com.vaadin.external.json.JSONException;
 import com.vaadin.external.json.JSONObject;
+import com.vaadin.external.json.JSONTokener;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
 import com.vaadin.terminal.gwt.client.communication.UidlValue;
@@ -66,7 +66,6 @@ public class JsonCodec implements Serializable {
         registerType(HashMap.class, JsonEncoder.VTYPE_MAP);
         registerType(List.class, JsonEncoder.VTYPE_LIST);
         registerType(Set.class, JsonEncoder.VTYPE_SET);
-        registerType(UidlValue.class, JsonEncoder.VTYPE_UIDL_VALUE);
     }
 
     private static void registerType(Class<?> type, String transportType) {
@@ -84,6 +83,10 @@ public class JsonCodec implements Serializable {
         if (type instanceof Class && ((Class<?>) type).isPrimitive()) {
             // All primitive types are handled internally
             return true;
+        } else if (type == UidlValue.class) {
+            // UidlValue is a special internal type wrapping type info and a
+            // value
+            return true;
         }
         return typeToTransportType.containsKey(getClassForType(type));
     }
@@ -101,32 +104,22 @@ public class JsonCodec implements Serializable {
     }
 
     public static Object decodeInternalOrCustomType(Type targetType,
-            JSONArray valueAndType, Application application)
-            throws JSONException {
+            Object value, Application application) throws JSONException {
         if (isInternalType(targetType)) {
-            return decodeInternalType(targetType, false, valueAndType,
-                    application);
+            return decodeInternalType(targetType, false, value, application);
         } else {
-            return decodeCustomType(targetType, valueAndType, application);
+            return decodeCustomType(targetType, value, application);
         }
     }
 
-    public static Object decodeCustomType(Type targetType,
-            JSONArray valueAndType, Application application)
-            throws JSONException {
+    public static Object decodeCustomType(Type targetType, Object value,
+            Application application) throws JSONException {
         if (isInternalType(targetType)) {
             throw new JSONException("decodeCustomType cannot be used for "
                     + targetType + ", which is an internal type");
         }
-        String transportType = getCustomTransportType(getClassForType(targetType));
-        String encodedTransportType = valueAndType.getString(0);
-        if (!transportTypesCompatible(encodedTransportType, transportType)) {
-            throw new JSONException("Expected a value of type " + transportType
-                    + ", received " + encodedTransportType);
-        }
 
         // Try to decode object using fields
-        Object value = valueAndType.get(1);
         if (value == JSONObject.NULL) {
             return null;
         } else {
@@ -159,29 +152,21 @@ public class JsonCodec implements Serializable {
      * @throws JSONException
      */
     public static Object decodeInternalType(Type targetType,
-            boolean restrictToInternalTypes, JSONArray valueAndType,
+            boolean restrictToInternalTypes, Object encodedJsonValue,
             Application application) throws JSONException {
-        String encodedTransportType = valueAndType.getString(0);
         if (!isInternalType(targetType)) {
             throw new JSONException("Type " + targetType
                     + " is not a supported internal type.");
         }
         String transportType = getInternalTransportType(targetType);
-        if (!transportTypesCompatible(encodedTransportType, transportType)) {
-            throw new JSONException("Expected a value of type " + targetType
-                    + ", received " + getType(encodedTransportType));
-        }
-
-        Object encodedJsonValue = valueAndType.get(1);
 
-        if (JsonEncoder.VTYPE_NULL.equals(encodedTransportType)) {
+        if (encodedJsonValue == JSONObject.NULL) {
             return null;
         }
 
-        // VariableChange
-        if (JsonEncoder.VTYPE_UIDL_VALUE.contentEquals(transportType)) {
-            return decodeVariableChange((JSONArray) encodedJsonValue,
-                    application);
+        // UidlValue
+        if (targetType == UidlValue.class) {
+            return decodeUidlValue((JSONArray) encodedJsonValue, application);
         }
 
         // Collections
@@ -233,14 +218,12 @@ public class JsonCodec implements Serializable {
         throw new JSONException("Unknown type " + transportType);
     }
 
-    private static UidlValue decodeVariableChange(JSONArray encodedJsonValue,
+    private static UidlValue decodeUidlValue(JSONArray encodedJsonValue,
             Application application) throws JSONException {
         String type = encodedJsonValue.getString(0);
 
-        JSONArray valueAndType = new JSONArray(Arrays.asList(type,
-                encodedJsonValue.get(1)));
         Object decodedValue = decodeInternalType(getType(type), true,
-                valueAndType, application);
+                encodedJsonValue.get(1), application);
         return new UidlValue(decodedValue);
     }
 
@@ -267,8 +250,8 @@ public class JsonCodec implements Serializable {
         Iterator<String> it = jsonMap.keys();
         while (it.hasNext()) {
             String key = it.next();
-            JSONArray encodedKey = new JSONArray(key);
-            JSONArray encodedValue = jsonMap.getJSONArray(key);
+            Object encodedKey = new JSONTokener(key).nextValue();
+            Object encodedValue = jsonMap.get(key);
 
             Object decodedKey = decodeParametrizedType(targetType,
                     restrictToInternalTypes, 0, encodedKey, application);
@@ -291,20 +274,18 @@ public class JsonCodec implements Serializable {
      * @throws JSONException
      */
     private static Object decodeParametrizedType(Type targetType,
-            boolean restrictToInternalTypes, int typeIndex,
-            JSONArray encodedValueAndType, Application application)
-            throws JSONException {
+            boolean restrictToInternalTypes, int typeIndex, Object value,
+            Application application) throws JSONException {
         if (!restrictToInternalTypes && targetType instanceof ParameterizedType) {
             Type childType = ((ParameterizedType) targetType)
                     .getActualTypeArguments()[typeIndex];
             // Only decode the given type
-            return decodeInternalOrCustomType(childType, encodedValueAndType,
-                    application);
+            return decodeInternalOrCustomType(childType, value, application);
         } else {
             // Only UidlValue when not enforcing a given type to avoid security
             // issues
             UidlValue decodeInternalType = (UidlValue) decodeInternalType(
-                    UidlValue.class, true, encodedValueAndType, application);
+                    UidlValue.class, true, value, application);
             return decodeInternalType.getValue();
         }
     }
@@ -391,8 +372,7 @@ public class JsonCodec implements Serializable {
                 if (fieldName == null) {
                     continue;
                 }
-                JSONArray encodedFieldValue = serializedObject
-                        .getJSONArray(fieldName);
+                Object encodedFieldValue = serializedObject.get(fieldName);
                 Type fieldType = pd.getReadMethod().getGenericReturnType();
                 Object decodedFieldValue = decodeInternalOrCustomType(
                         fieldType, encodedFieldValue, application);