]> source.dussan.org Git - vaadin-framework.git/commitdiff
Encode all values based on declared type (#10549) 17/517/3
authorLeif Åstrand <leif@vaadin.com>
Tue, 18 Dec 2012 13:07:21 +0000 (15:07 +0200)
committerVaadin Code Review <review@vaadin.com>
Tue, 18 Dec 2012 13:35:12 +0000 (13:35 +0000)
* ServerRpc encoding uses type data from the interface
* Beans encoded on the server use reflection based on declared type
* Remove row numbers to enable adding test without changing old indices
* Update test to send non-primitive map values

Change-Id: I0462b547cb7de252564b3569420b0b24cee4515f

client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ArraySerializer.java
client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ServerRpcVisitor.java
client/src/com/vaadin/client/ApplicationConnection.java
client/src/com/vaadin/client/communication/JsonEncoder.java
client/src/com/vaadin/client/communication/URLReference_Serializer.java
server/src/com/vaadin/server/JsonCodec.java
uitest/src/com/vaadin/tests/serialization/SerializerTest.html
uitest/src/com/vaadin/tests/serialization/SerializerTest.java
uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java
uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java

index 4ab5cccb2e998dfeaa4a12f7a3683cd5b6b682c0..7b326c65fc71ca1d4851b8ee035d4552149b8c34 100644 (file)
@@ -73,14 +73,17 @@ public class ArraySerializer extends JsonSerializer {
     @Override
     protected void printSerializerBody(TreeLogger logger, SourceWriter w,
             String value, String applicationConnection) {
+        JType componentType = arrayType.getComponentType();
+
         w.println(JSONArray.class.getName() + " values = new "
                 + JSONArray.class.getName() + "();");
         // JPrimitiveType primitive = componentType.isPrimitive();
         w.println("for (int i = 0; i < " + value + ".length; i++) {");
         w.indent();
         w.print("values.set(i, ");
-        w.print(JsonEncoder.class.getName() + ".encode(" + value
-                + "[i], false, " + applicationConnection + ")");
+        w.print(JsonEncoder.class.getName() + ".encode(" + value + "[i],");
+        ConnectorBundleLoaderFactory.writeTypeCreator(w, componentType);
+        w.print(", " + applicationConnection + ")");
         w.println(");");
         w.outdent();
         w.println("}");
index fa0a8390a4b4dbf7b42b41da56da3f19f1e2cb27..e14e8234d50410c10c61695af34ad5dacddc3fd1 100644 (file)
@@ -38,6 +38,7 @@ public class ServerRpcVisitor extends TypeVisitor {
                 for (JMethod method : methods) {
                     ClientRpcVisitor.checkReturnType(logger, method);
                     bundle.setNeedsDelayedInfo(type, method);
+                    bundle.setNeedsParamTypes(subType, method);
 
                     JType[] parameterTypes = method.getParameterTypes();
                     for (JType paramType : parameterTypes) {
index ff59a76832d90789cab972b940831515e60941b1..00b0d75c6c43e1420de2c1ffd4e9ee358b7d58ec 100644 (file)
@@ -71,6 +71,7 @@ import com.vaadin.client.communication.RpcManager;
 import com.vaadin.client.communication.StateChangeEvent;
 import com.vaadin.client.extensions.AbstractExtensionConnector;
 import com.vaadin.client.metadata.ConnectorBundleLoader;
+import com.vaadin.client.metadata.Method;
 import com.vaadin.client.metadata.NoDataException;
 import com.vaadin.client.metadata.Property;
 import com.vaadin.client.metadata.Type;
@@ -2393,12 +2394,29 @@ public class ApplicationConnection {
                 invocationJson.set(2,
                         new JSONString(invocation.getMethodName()));
                 JSONArray paramJson = new JSONArray();
-                boolean restrictToInternalTypes = isLegacyVariableChange(invocation);
+
+                Type[] parameterTypes = null;
+                if (!isLegacyVariableChange(invocation)) {
+                    try {
+                        Type type = new Type(invocation.getInterfaceName(),
+                                null);
+                        Method method = type.getMethod(invocation
+                                .getMethodName());
+                        parameterTypes = method.getParameterTypes();
+                    } catch (NoDataException e) {
+                        throw new RuntimeException("No type data for "
+                                + invocation.toString(), e);
+                    }
+                }
+
                 for (int i = 0; i < invocation.getParameters().length; ++i) {
-                    // TODO non-static encoder? type registration?
-                    paramJson.set(i, JsonEncoder.encode(
-                            invocation.getParameters()[i],
-                            restrictToInternalTypes, this));
+                    // TODO non-static encoder?
+                    Type type = null;
+                    if (parameterTypes != null) {
+                        type = parameterTypes[i];
+                    }
+                    Object value = invocation.getParameters()[i];
+                    paramJson.set(i, JsonEncoder.encode(value, type, this));
                 }
                 invocationJson.set(3, paramJson);
                 reqJson.set(reqJson.size(), invocationJson);
index 0756d6b069ea7ec87fc791f4675cf517f09b289e..f3262c01066e5b2bdc67fd58b1d2dd6ddc4f3f08 100644 (file)
@@ -59,8 +59,8 @@ public class JsonEncoder {
      * @param connection
      * @return JSON representation of the value
      */
-    public static JSONValue encode(Object value,
-            boolean restrictToInternalTypes, ApplicationConnection connection) {
+    public static JSONValue encode(Object value, Type type,
+            ApplicationConnection connection) {
         if (null == value) {
             return JSONNull.getInstance();
         } else if (value instanceof JSONValue) {
@@ -80,55 +80,58 @@ public class JsonEncoder {
             return new JSONNumber((Byte) value);
         } else if (value instanceof Character) {
             return new JSONString(String.valueOf(value));
-        } else if (value instanceof Object[]) {
-            return encodeObjectArray((Object[]) value, restrictToInternalTypes,
-                    connection);
+        } else if (value instanceof Object[] && type == null) {
+            // Non-legacy arrays handed by generated serializer
+            return encodeLegacyObjectArray((Object[]) value, connection);
         } else if (value instanceof Enum) {
             return encodeEnum((Enum<?>) value, connection);
         } else if (value instanceof Map) {
-            return encodeMap((Map) value, restrictToInternalTypes, connection);
+            return encodeMap((Map) value, type, connection);
         } else if (value instanceof Connector) {
             Connector connector = (Connector) value;
             return new JSONString(connector.getConnectorId());
         } else if (value instanceof Collection) {
-            return encodeCollection((Collection) value,
-                    restrictToInternalTypes, connection);
+            return encodeCollection((Collection) value, type, connection);
         } else if (value instanceof UidlValue) {
             return encodeVariableChange((UidlValue) value, connection);
         } else {
+            // First see if there's a custom serializer
+            JSONSerializer<Object> serializer = null;
+            if (type != null) {
+                serializer = (JSONSerializer<Object>) type.findSerializer();
+                if (serializer != null) {
+                    return serializer.serialize(value, connection);
+                }
+            }
+
             String transportType = getTransportType(value);
             if (transportType != null) {
+                // Send the string value for remaining legacy types
                 return new JSONString(String.valueOf(value));
-            } else {
-                // Try to find a generated serializer object, class name is the
-                // type
-                Type type = new Type(value.getClass());
-
-                JSONSerializer<Object> serializer = (JSONSerializer<Object>) type
-                        .findSerializer();
-                if (serializer != null) {
-                    return serializer.serialize(value, connection);
-                } else {
-                    try {
-                        Collection<Property> properties = type.getProperties();
-
-                        JSONObject jsonObject = new JSONObject();
-                        for (Property property : properties) {
-                            Object propertyValue = property.getValue(value);
-                            JSONValue encodedPropertyValue = encode(
-                                    propertyValue, restrictToInternalTypes,
-                                    connection);
-                            jsonObject.put(property.getName(),
-                                    encodedPropertyValue);
-                        }
-                        return jsonObject;
-
-                    } catch (NoDataException e) {
-                        throw new RuntimeException("Can not encode "
-                                + type.getSignature(), e);
+            } else if (type != null) {
+                // And finally try using bean serialization logic
+                try {
+                    Collection<Property> properties = type.getProperties();
+
+                    JSONObject jsonObject = new JSONObject();
+                    for (Property property : properties) {
+                        Object propertyValue = property.getValue(value);
+                        Type propertyType = property.getType();
+                        JSONValue encodedPropertyValue = encode(propertyValue,
+                                propertyType, connection);
+                        jsonObject
+                                .put(property.getName(), encodedPropertyValue);
                     }
+                    return jsonObject;
+
+                } catch (NoDataException e) {
+                    throw new RuntimeException("Can not encode "
+                            + type.getSignature(), e);
                 }
 
+            } else {
+                throw new RuntimeException("Can't encode " + value.getClass()
+                        + " without type information");
             }
         }
     }
@@ -152,13 +155,13 @@ public class JsonEncoder {
                     + valueType);
         }
         jsonArray.set(0, new JSONString(transportType));
-        jsonArray.set(1, encode(value, true, connection));
+        jsonArray.set(1, encode(value, null, connection));
 
         return jsonArray;
     }
 
-    private static JSONValue encodeMap(Map<Object, Object> map,
-            boolean restrictToInternalTypes, ApplicationConnection connection) {
+    private static JSONValue encodeMap(Map<Object, Object> map, Type type,
+            ApplicationConnection connection) {
         /*
          * As we have no info about declared types, we instead select encoding
          * scheme based on actual type of first key. We can't do this if there's
@@ -171,26 +174,43 @@ public class JsonEncoder {
 
         Object firstKey = map.keySet().iterator().next();
         if (firstKey instanceof String) {
-            return encodeStringMap(map, restrictToInternalTypes, connection);
-        } else if (restrictToInternalTypes) {
+            return encodeStringMap(map, type, connection);
+        } else if (type == null) {
             throw new IllegalStateException(
                     "Only string keys supported for legacy maps");
         } else if (firstKey instanceof Connector) {
-            return encodeConnectorMap(map, connection);
+            return encodeConnectorMap(map, type, connection);
         } else {
-            return encodeObjectMap(map, connection);
+            return encodeObjectMap(map, type, connection);
+        }
+    }
+
+    private static JSONValue encodeChildValue(Object value,
+            Type collectionType, int typeIndex, ApplicationConnection connection) {
+        if (collectionType == null) {
+            return encode(new UidlValue(value), null, connection);
+        } else {
+            assert collectionType.getParameterTypes() != null
+                    && collectionType.getParameterTypes().length > typeIndex
+                    && collectionType.getParameterTypes()[typeIndex] != null : "Proper generics required for encoding child value, assertion failed for "
+                    + collectionType;
+            Type childType = collectionType.getParameterTypes()[typeIndex];
+            return encode(value, childType, connection);
         }
     }
 
     private static JSONValue encodeObjectMap(Map<Object, Object> map,
-            ApplicationConnection connection) {
+            Type type, ApplicationConnection connection) {
         JSONArray keys = new JSONArray();
         JSONArray values = new JSONArray();
+
+        assert type != null : "Should only be used for non-legacy types";
+
         for (Entry<?, ?> entry : map.entrySet()) {
-            // restrictToInternalTypes always false if we end up here
-            keys.set(keys.size(), encode(entry.getKey(), false, connection));
+            keys.set(keys.size(),
+                    encodeChildValue(entry.getKey(), type, 0, connection));
             values.set(values.size(),
-                    encode(entry.getValue(), false, connection));
+                    encodeChildValue(entry.getValue(), type, 1, connection));
         }
 
         JSONArray keysAndValues = new JSONArray();
@@ -201,14 +221,14 @@ public class JsonEncoder {
     }
 
     private static JSONValue encodeConnectorMap(Map<Object, Object> map,
-            ApplicationConnection connection) {
+            Type type, ApplicationConnection connection) {
         JSONObject jsonMap = new JSONObject();
 
         for (Entry<?, ?> entry : map.entrySet()) {
             Connector connector = (Connector) entry.getKey();
 
-            // restrictToInternalTypes always false if we end up here
-            JSONValue encodedValue = encode(entry.getValue(), false, connection);
+            JSONValue encodedValue = encodeChildValue(entry.getValue(), type,
+                    1, connection);
 
             jsonMap.put(connector.getConnectorId(), encodedValue);
         }
@@ -217,21 +237,14 @@ public class JsonEncoder {
     }
 
     private static JSONValue encodeStringMap(Map<Object, Object> map,
-            boolean restrictToInternalTypes, ApplicationConnection connection) {
+            Type type, ApplicationConnection connection) {
         JSONObject jsonMap = new JSONObject();
 
         for (Entry<?, ?> entry : map.entrySet()) {
             String key = (String) entry.getKey();
             Object value = entry.getValue();
 
-            if (restrictToInternalTypes) {
-                value = new UidlValue(value);
-            }
-
-            JSONValue encodedValue = encode(value, restrictToInternalTypes,
-                    connection);
-
-            jsonMap.put(key, encodedValue);
+            jsonMap.put(key, encodeChildValue(value, type, 1, connection));
         }
 
         return jsonMap;
@@ -242,28 +255,23 @@ public class JsonEncoder {
         return new JSONString(e.toString());
     }
 
-    private static JSONValue encodeObjectArray(Object[] array,
-            boolean restrictToInternalTypes, ApplicationConnection connection) {
+    private static JSONValue encodeLegacyObjectArray(Object[] array,
+            ApplicationConnection connection) {
         JSONArray jsonArray = new JSONArray();
         for (int i = 0; i < array.length; ++i) {
             // TODO handle object graph loops?
             Object value = array[i];
-            if (restrictToInternalTypes) {
-                value = new UidlValue(value);
-            }
-            jsonArray
-                    .set(i, encode(value, restrictToInternalTypes, connection));
+            jsonArray.set(i, encode(value, null, connection));
         }
         return jsonArray;
     }
 
-    private static JSONValue encodeCollection(Collection collection,
-            boolean restrictToInternalTypes, ApplicationConnection connection) {
+    private static JSONValue encodeCollection(Collection collection, Type type,
+            ApplicationConnection connection) {
         JSONArray jsonArray = new JSONArray();
         int idx = 0;
         for (Object o : collection) {
-            JSONValue encodedObject = encode(o, restrictToInternalTypes,
-                    connection);
+            JSONValue encodedObject = encodeChildValue(o, type, 0, connection);
             jsonArray.set(idx++, encodedObject);
         }
         if (collection instanceof Set) {
index f004980e5699e55d8b284fff6a908abcecf2d586..e455d4ee93d759dfc232b0a3b090847c0bc1c070 100644 (file)
@@ -46,8 +46,9 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> {
     public JSONValue serialize(URLReference value,
             ApplicationConnection connection) {
         JSONObject json = new JSONObject();
+        // No type info required for encoding a String...
         json.put(URL_FIELD,
-                JsonEncoder.encode(value.getURL(), true, connection));
+                JsonEncoder.encode(value.getURL(), null, connection));
         return json;
     }
 
index f7cbe79fdb7eae36887fb272b97042b80f26919b..aeda8f622fd4ac4c3b86316613ceea4ab375d5f1 100644 (file)
@@ -666,10 +666,13 @@ public class JsonCodec implements Serializable {
             return encodeEnum((Enum<?>) value, connectorTracker);
         } else if (value instanceof JSONArray || value instanceof JSONObject) {
             return new EncodeResult(value);
-        } else {
+        } else if (valueType instanceof Class<?>) {
             // Any object that we do not know how to encode we encode by looping
             // through fields
-            return encodeObject(value, (JSONObject) diffState, connectorTracker);
+            return encodeObject(value, (Class<?>) valueType,
+                    (JSONObject) diffState, connectorTracker);
+        } else {
+            throw new JSONException("Can not encode " + valueType);
         }
     }
 
@@ -687,14 +690,14 @@ public class JsonCodec implements Serializable {
         return properties;
     }
 
-    private static EncodeResult encodeObject(Object value,
+    private static EncodeResult encodeObject(Object value, Class<?> valueType,
             JSONObject referenceValue, ConnectorTracker connectorTracker)
             throws JSONException {
         JSONObject encoded = new JSONObject();
         JSONObject diff = new JSONObject();
 
         try {
-            for (BeanProperty property : getProperties(value.getClass())) {
+            for (BeanProperty property : getProperties(valueType)) {
                 String fieldName = property.getName();
                 // We can't use PropertyDescriptor.getPropertyType() as it does
                 // not support generics
@@ -704,7 +707,7 @@ public class JsonCodec implements Serializable {
                 if (encoded.has(fieldName)) {
                     throw new RuntimeException(
                             "Can't encode "
-                                    + value.getClass().getName()
+                                    + valueType.getName()
                                     + " as it has multiple properties with the name "
                                     + fieldName.toLowerCase()
                                     + ". This can happen if there are getters and setters for a public field (the framework can't know which to ignore) or if there are properties with only casing distinguishing between the names (e.g. getFoo() and getFOO())");
index 46b1a9ed8b1d5a6e66f138c42a64e1cf3e7f1ba6..63219de5c248ca67509886ed9f949830666fe81e 100644 (file)
        <td>/run/com.vaadin.tests.serialization.SerializerTest?restartApplication</td>
        <td></td>
 </tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[18]</td>
+       <td>sendBeanSubclass: 43</td>
+</tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[17]</td>
-       <td>1. sendBoolean: false, false, [false, false, true, false, true, true]</td>
+       <td>sendBoolean: false, false, [false, false, true, false, true, true]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[16]</td>
-       <td>2. sendByte: 5, -12, [3, 1, 2]</td>
+       <td>sendByte: 5, -12, [3, 1, 2]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[15]</td>
-       <td>3. sendChar: Å, ∫, [a, b, c, d]</td>
+       <td>sendChar: Å, ∫, [a, b, c, d]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[14]</td>
-       <td>4. sendInt: 2, 5, [2147483647, 0]</td>
+       <td>sendInt: 2, 5, [2147483647, 0]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[13]</td>
-       <td>5. sendLong: -57841235865, 577431841358, [57, 0]</td>
+       <td>sendLong: -57841235865, 577431841358, [57, 0]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[12]</td>
-       <td>6. sendFloat: 1.0000001, 3.14159, [-12.0, 0.0, 57.0]</td>
+       <td>sendFloat: 1.0000001, 3.14159, [-12.0, 0.0, 57.0]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[11]</td>
-       <td>7. sendDouble: 0.423310825130748, 5.859874482048838, [2.0, 1.7976931348623157E308, 4.9E-324]</td>
+       <td>sendDouble: 0.423310825130748, 5.859874482048838, [2.0, 1.7976931348623157E308, 4.9E-324]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[10]</td>
-       <td>8. sendString: Taegghiiiinnrsssstt‡</td>
+       <td>sendString: Taegghiiiinnrsssstt‡</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[9]</td>
-       <td>9. sendConnector: com.vaadin.tests.widgetset.server.SerializerTestExtension</td>
+       <td>sendConnector: com.vaadin.tests.widgetset.server.SerializerTestExtension</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[8]</td>
-       <td>10. sendBean: ComplexTestBean [innerBean1=SimpleTestBean(1), innerBean2=SimpleTestBean(3), innerBeanCollection=[SimpleTestBean(6), SimpleTestBean(0)], privimite=6], SimpleTestBean(0), [SimpleTestBean(7)]</td>
+       <td>sendBean: ComplexTestBean [innerBean1=SimpleTestBean(1), innerBean2=SimpleTestBean(3), innerBeanCollection=[SimpleTestBean(6), SimpleTestBean(0)], privimite=6], SimpleTestBean(0), [SimpleTestBean(7)]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[7]</td>
-       <td>11. sendNull: null, Not null</td>
+       <td>sendNull: null, Not null</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[6]</td>
-       <td>12. sendNestedArray: [[7, 5]], [[SimpleTestBean(2)], [SimpleTestBean(4)]]</td>
+       <td>sendNestedArray: [[7, 5]], [[SimpleTestBean(2)], [SimpleTestBean(4)]]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[5]</td>
-       <td>13. sendList: [-234, 5, 8], class com.vaadin.tests.widgetset.server.SerializerTestExtension, class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(-568), SimpleTestBean(234)]</td>
+       <td>sendList: [-234, 5, 8], class com.vaadin.tests.widgetset.server.SerializerTestExtension, class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(-568), SimpleTestBean(234)]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[4]</td>
-       <td>14. sendArrayList: [[2], [2]], [[2, 1], [2, 3]], [[SimpleTestBean(7)]]</td>
+       <td>sendArrayList: [[2], [2]], [[2, 1], [2, 3]], [[SimpleTestBean(7)]]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[3]</td>
-       <td>15. sendSet: [-12, -7, -4], class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(2), SimpleTestBean(3)]</td>
+       <td>sendSet: [-12, -7, -4], class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(2), SimpleTestBean(3)]</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[2]</td>
-       <td>16. sendMap: {a=null}, [com.vaadin.tests.widgetset.server.SerializerTestExtension=false], [2=com.vaadin.tests.widgetset.server.SerializerTestExtension], {SimpleTestBean(4)=SimpleTestBean(-4), SimpleTestBean(-5)=SimpleTestBean(5)}</td>
+       <td>sendMap: {a=SimpleTestBean(1)}, [com.vaadin.tests.widgetset.server.SerializerTestExtension=SimpleTestBean(4)], [2=com.vaadin.tests.widgetset.server.SerializerTestExtension], {SimpleTestBean(4)=SimpleTestBean(-4), SimpleTestBean(-5)=SimpleTestBean(5)}</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[1]</td>
-       <td>17. sendWrappedGenerics: {[SimpleTestBean(1)]={1=[SimpleTestBean(42)]}}</td>
+       <td>sendWrappedGenerics: {[SimpleTestBean(1)]={1=[SimpleTestBean(42)]}}</td>
 </tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]</td>
-       <td>18. sendEnum: PREFORMATTED, [HTML, RAW], [PREFORMATTED, XML]</td>
+       <td>sendEnum: PREFORMATTED, [HTML, RAW], [PREFORMATTED, XML]</td>
 </tr>
 </tbody></table>
 </body>
index e7acd3e79be717f7ee5bc12a0f30a146133dd491..efadf8c23796dd680d76fb2fc236e4d6524ad870 100644 (file)
@@ -46,10 +46,20 @@ public class SerializerTest extends AbstractTestUI {
     protected void setup(VaadinRequest request) {
         final SerializerTestExtension testExtension = new SerializerTestExtension();
         addExtension(testExtension);
+
+        // Don't show row numbers to make it easier to add tests without
+        // changing all numbers
+        log.setNumberLogRows(false);
         addComponent(log);
 
         SerializerTestRpc rpc = testExtension
                 .getRpcProxy(SerializerTestRpc.class);
+        rpc.sendBeanSubclass(new SimpleTestBean() {
+            @Override
+            public int getValue() {
+                return 42;
+            }
+        });
         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 });
@@ -95,10 +105,10 @@ public class SerializerTest extends AbstractTestUI {
                 put("1", new SimpleTestBean(1));
                 put("2", new SimpleTestBean(2));
             }
-        }, new HashMap<Connector, Boolean>() {
+        }, new HashMap<Connector, SimpleTestBean>() {
             {
-                put(testExtension, true);
-                put(getUI(), false);
+                put(testExtension, new SimpleTestBean(3));
+                put(getUI(), new SimpleTestBean(4));
             }
         }, new HashMap<Integer, Connector>() {
             {
@@ -252,11 +262,12 @@ public class SerializerTest extends AbstractTestUI {
 
             @Override
             public void sendMap(Map<String, SimpleTestBean> stringMap,
-                    Map<Connector, Boolean> connectorMap,
+                    Map<Connector, SimpleTestBean> connectorMap,
                     Map<Integer, Connector> intMap,
                     Map<SimpleTestBean, SimpleTestBean> beanMap) {
                 StringBuilder sb = new StringBuilder();
-                for (Entry<Connector, Boolean> entry : connectorMap.entrySet()) {
+                for (Entry<Connector, SimpleTestBean> entry : connectorMap
+                        .entrySet()) {
                     if (sb.length() == 0) {
                         sb.append('[');
                     } else {
@@ -300,6 +311,11 @@ public class SerializerTest extends AbstractTestUI {
                         + Arrays.toString(array) + ", " + list);
             }
 
+            @Override
+            public void sendBeanSubclass(SimpleTestBean bean) {
+                log.log("sendBeanSubclass: " + bean.getValue());
+            }
+
         });
     }
 
index 90cce49ace1f0e290aed275575e32f4f377e6741..9c2b1a71fab3938a4a6881322793b44538a280cc 100644 (file)
@@ -93,7 +93,7 @@ public class SerializerTestConnector extends AbstractExtensionConnector {
 
             @Override
             public void sendMap(Map<String, SimpleTestBean> stringMap,
-                    Map<Connector, Boolean> connectorMap,
+                    Map<Connector, SimpleTestBean> connectorMap,
                     Map<Integer, Connector> intMap,
                     Map<SimpleTestBean, SimpleTestBean> beanMap) {
                 Map<SimpleTestBean, SimpleTestBean> updatedBeanMap = new HashMap<SimpleTestBean, SimpleTestBean>();
@@ -102,7 +102,7 @@ public class SerializerTestConnector extends AbstractExtensionConnector {
                     updatedBeanMap.put(entry.getValue(), entry.getKey());
                 }
 
-                rpc.sendMap(Collections.singletonMap("a", stringMap.get("b")),
+                rpc.sendMap(Collections.singletonMap("a", stringMap.get("1")),
                         Collections.singletonMap(getThisConnector(),
                                 connectorMap.get(getUIConnector())),
                         Collections.singletonMap(
@@ -241,6 +241,16 @@ public class SerializerTestConnector extends AbstractExtensionConnector {
                         list.toArray(new ContentMode[list.size()]),
                         Arrays.asList(array));
             }
+
+            @Override
+            public void sendBeanSubclass(final SimpleTestBean bean) {
+                rpc.sendBeanSubclass(new SimpleTestBean() {
+                    @Override
+                    public int getValue() {
+                        return bean.getValue() + 1;
+                    }
+                });
+            }
         });
     }
 
index 0d89976ca0578f1cef793703b9f56c3a899bb500..56874d973a551abdfcc8a05fca3dbbb8cec42ae7 100644 (file)
@@ -67,7 +67,7 @@ public interface SerializerTestRpc extends ServerRpc, ClientRpc {
             Set<SimpleTestBean> beanSet);
 
     public void sendMap(Map<String, SimpleTestBean> stringMap,
-            Map<Connector, Boolean> connectorMap,
+            Map<Connector, SimpleTestBean> connectorMap,
             Map<Integer, Connector> intMap,
             Map<SimpleTestBean, SimpleTestBean> beanMap);
 
@@ -77,4 +77,6 @@ public interface SerializerTestRpc extends ServerRpc, ClientRpc {
     public void sendEnum(ContentMode contentMode, ContentMode[] array,
             List<ContentMode> list);
 
+    public void sendBeanSubclass(SimpleTestBean bean);
+
 }