]> source.dussan.org Git - vaadin-framework.git/commitdiff
Added support for serializing enums (#8675)
authorArtur Signell <artur@vaadin.com>
Thu, 3 May 2012 21:28:25 +0000 (00:28 +0300)
committerArtur Signell <artur@vaadin.com>
Fri, 11 May 2012 19:18:27 +0000 (22:18 +0300)
Changed JSONSerializer to use JSONValue instead of JSONObject

src/com/vaadin/terminal/gwt/client/communication/JSONSerializer.java
src/com/vaadin/terminal/gwt/client/communication/JsonDecoder.java
src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java
src/com/vaadin/terminal/gwt/client/communication/URLReference_Serializer.java
src/com/vaadin/terminal/gwt/server/JsonCodec.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java

index 5f82e339f463b8a5a5a009f43296f4ea05e3ee54..f7b3df6b05951ff4a35cf7d70d6e032f52007afe 100644 (file)
@@ -5,6 +5,7 @@
 package com.vaadin.terminal.gwt.client.communication;
 
 import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONValue;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
 import com.vaadin.terminal.gwt.server.JsonCodec;
@@ -40,7 +41,7 @@ public interface JSONSerializer<T> {
      *            references to paintables
      * @return A deserialized object
      */
-    T deserialize(JSONObject jsonValue, T target, ConnectorMap idMapper,
+    T deserialize(JSONValue jsonValue, T target, ConnectorMap idMapper,
             ApplicationConnection connection);
 
     /**
@@ -56,7 +57,7 @@ public interface JSONSerializer<T> {
      *            references to paintables
      * @return A JSON serialized version of the object
      */
-    JSONObject serialize(T value, ConnectorMap idMapper,
+    JSONValue serialize(T value, ConnectorMap idMapper,
             ApplicationConnection connection);
 
 }
index 790b5cb3054fd5c296a6d87298bfbb0ff17f0f34..d7cf764f75f4d4711cd038031f99d784991e9a77 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Set;
 import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONObject;
 import com.google.gwt.json.client.JSONString;
+import com.google.gwt.json.client.JSONValue;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
@@ -52,7 +53,7 @@ public class JsonDecoder {
         return decodeValue(type, jsonArray.get(1), target, idMapper, connection);
     }
 
-    private static Object decodeValue(String variableType, Object value,
+    private static Object decodeValue(String variableType, JSONValue value,
             Object target, ConnectorMap idMapper,
             ApplicationConnection connection) {
         Object val = null;
@@ -91,15 +92,15 @@ public class JsonDecoder {
         } else if (JsonEncoder.VTYPE_CONNECTOR.equals(variableType)) {
             val = idMapper.getConnector(((JSONString) value).stringValue());
         } else {
-            return decodeObject(variableType, (JSONObject) value, target,
-                    idMapper, connection);
+            return decodeObject(variableType, value, target, idMapper,
+                    connection);
         }
 
         return val;
     }
 
     private static Object decodeObject(String variableType,
-            JSONObject encodedValue, Object target, ConnectorMap idMapper,
+            JSONValue encodedValue, Object target, ConnectorMap idMapper,
             ApplicationConnection connection) {
         // object, class name as type
         JSONSerializer<Object> serializer = connection.getSerializerMap()
index 4a3515ff133551f470b33242aa4c8783d703ac26..599022b78cfcea7cea6371ac52915a766ed4444c 100644 (file)
@@ -80,6 +80,9 @@ public class JsonEncoder {
                     JSONBoolean.getInstance((Boolean) value));
         } else if (value instanceof Object[]) {
             return encodeObjectArray((Object[]) value, connectorMap, connection);
+        } else if (value instanceof Enum) {
+            Enum e = (Enum) value;
+            return encodeEnum(e, connectorMap, connection);
         } else if (value instanceof Map) {
             Map<Object, Object> map = (Map<Object, Object>) value;
             JSONObject jsonMap = new JSONObject();
@@ -127,6 +130,12 @@ public class JsonEncoder {
         }
     }
 
+    private static JSONValue encodeEnum(Enum e, ConnectorMap connectorMap,
+            ApplicationConnection connection) {
+        return combineTypeAndValue(e.getClass().getName(),
+                new JSONString(e.toString()));
+    }
+
     private static JSONValue encodeObjectArray(Object[] array,
             ConnectorMap connectorMap, ApplicationConnection connection) {
         JSONArray jsonArray = new JSONArray();
@@ -193,8 +202,6 @@ public class JsonEncoder {
             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[]) {
             return VTYPE_STRINGARRAY;
         } else if (value instanceof Object[]) {
index 27a0d0118edfa03e700bb5b31c0ec7e20e90309e..3ddae493b722e9eaecce93c7c49851e4d8bdbf14 100644 (file)
@@ -6,16 +6,18 @@ package com.vaadin.terminal.gwt.client.communication;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONValue;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ConnectorMap;
 
 public class URLReference_Serializer implements JSONSerializer<URLReference> {
 
-    public URLReference deserialize(JSONObject jsonValue, URLReference target,
+    public URLReference deserialize(JSONValue jsonValue, URLReference target,
             ConnectorMap idMapper, ApplicationConnection connection) {
         URLReference reference = GWT.create(URLReference.class);
-        if (jsonValue.containsKey("URL")) {
-            JSONArray jsonURL = (JSONArray) jsonValue.get("URL");
+        JSONObject json = (JSONObject) jsonValue;
+        if (json.containsKey("URL")) {
+            JSONArray jsonURL = (JSONArray) json.get("URL");
             String URL = (String) JsonDecoder.decodeValue(jsonURL, null,
                     idMapper, connection);
             reference.setURL(connection.translateVaadinUri(URL));
@@ -23,7 +25,7 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> {
         return reference;
     }
 
-    public JSONObject serialize(URLReference value, ConnectorMap idMapper,
+    public JSONValue serialize(URLReference value, ConnectorMap idMapper,
             ApplicationConnection connection) {
         JSONObject json = new JSONObject();
         json.put("URL",
index c88a1c828c7eb323ed3dee3a10b1642baa0c0a44..750aa7c15b062fa07fdc879cf88d9a2461681e37 100644 (file)
@@ -321,6 +321,11 @@ public class JsonCodec implements Serializable {
         }
     }
 
+    private static Object decodeEnum(Class<? extends Enum> cls, JSONObject value) {
+        String enumIdentifier = String.valueOf(value);
+        return Enum.valueOf(cls, enumIdentifier);
+    }
+
     private static String[] decodeStringArray(JSONArray jsonArray)
             throws JSONException {
         int length = jsonArray.length();
@@ -384,6 +389,11 @@ public class JsonCodec implements Serializable {
             throws JSONException {
 
         Class<?> targetClass = getClassForType(targetType);
+        if (Enum.class.isAssignableFrom(targetClass)) {
+            return decodeEnum(targetClass.asSubclass(Enum.class),
+                    serializedObject);
+        }
+
         try {
             Object decodedObject = targetClass.newInstance();
             for (PropertyDescriptor pd : Introspector.getBeanInfo(targetClass)
@@ -484,6 +494,8 @@ public class JsonCodec implements Serializable {
         } else if (internalTransportType != null) {
             return combineTypeAndValue(internalTransportType,
                     String.valueOf(value));
+        } else if (value instanceof Enum) {
+            return encodeEnum((Enum) value, application);
         } else {
             // Any object that we do not know how to encode we encode by looping
             // through fields
@@ -558,6 +570,12 @@ public class JsonCodec implements Serializable {
         return false;
     }
 
+    private static JSONArray encodeEnum(Enum e, Application application)
+            throws JSONException {
+        String enumIdentifier = e.name();
+        return combineTypeAndValue(e.getClass().getName(), enumIdentifier);
+    }
+
     private static JSONArray encodeArrayContents(Object[] array,
             Application application) throws JSONException {
         JSONArray jsonArray = new JSONArray();
index 3b6ab8cdba277502e78d8fbd5ae9db582e595490..0f0ca8042699c2813a3fb30b769302667924acf1 100644 (file)
@@ -16,12 +16,16 @@ import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.TreeLogger.Type;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JEnumConstant;
+import com.google.gwt.core.ext.typeinfo.JEnumType;
 import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONString;
+import com.google.gwt.json.client.JSONValue;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
@@ -89,6 +93,8 @@ public class SerializerGenerator extends Generator {
         if (printWriter == null) {
             return;
         }
+        boolean isEnum = (beanType.isEnum() != null);
+
         Date date = new Date();
         TypeOracle typeOracle = context.getTypeOracle();
         String beanQualifiedSourceName = beanType.getQualifiedSourceName();
@@ -117,7 +123,7 @@ public class SerializerGenerator extends Generator {
 
         // public JSONValue serialize(Object value, ConnectorMap idMapper,
         // ApplicationConnection connection) {
-        sourceWriter.println("public " + JSONObject.class.getName()
+        sourceWriter.println("public " + JSONValue.class.getName()
                 + " serialize(" + beanQualifiedSourceName + " value, "
                 + ConnectorMap.class.getName() + " idMapper, "
                 + ApplicationConnection.class.getName() + " connection) {");
@@ -125,48 +131,75 @@ public class SerializerGenerator extends Generator {
         // MouseEventDetails castedValue = (MouseEventDetails) value;
         sourceWriter.println(beanQualifiedSourceName + " castedValue = ("
                 + beanQualifiedSourceName + ") value;");
-        // JSONObject json = new JSONObject();
-        sourceWriter.println(JSONObject.class.getName() + " json = new "
-                + JSONObject.class.getName() + "();");
 
-        for (JMethod setterMethod : getSetters(beanType)) {
-            String setterName = setterMethod.getName();
-            String fieldName = setterName.substring(3); // setZindex() -> ZIndex
-            String getterName = findGetter(beanType, setterMethod);
-
-            if (getterName == null) {
-                logger.log(TreeLogger.ERROR, "No getter found for " + fieldName
-                        + ". Serialization will likely fail");
-            }
-            // json.put("button",
-            // JsonEncoder.encode(castedValue.getButton(), idMapper,
-            // connection));
-            sourceWriter.println("json.put(\"" + fieldName + "\", "
-                    + JsonEncoder.class.getName() + ".encode(castedValue."
-                    + getterName + "(), idMapper, connection));");
+        if (isEnum) {
+            writeEnumSerializer(logger, sourceWriter, beanType);
+        } else {
+            writeBeanSerializer(logger, sourceWriter, beanType);
         }
-        // return json;
-        sourceWriter.println("return json;");
         // }
         sourceWriter.println("}");
 
         // Deserializer
         sourceWriter.println("public " + beanQualifiedSourceName
-                + " deserialize(" + JSONObject.class.getName() + " jsonValue, "
+                + " deserialize(" + JSONValue.class.getName() + " jsonValue, "
                 + beanQualifiedSourceName + " target, "
                 + ConnectorMap.class.getName() + " idMapper, "
                 + ApplicationConnection.class.getName() + " connection) {");
         sourceWriter.indent();
 
+        if (isEnum) {
+            writeEnumDeserializer(logger, sourceWriter, beanType.isEnum());
+        } else {
+            writeBeanDeserializer(logger, sourceWriter, beanType);
+        }
+        sourceWriter.println("}");
+        sourceWriter.outdent();
+
+        // End of class
+        sourceWriter.println("}");
+        sourceWriter.outdent();
+
+        // commit generated class
+        context.commit(logger, printWriter);
+        logger.log(TreeLogger.INFO, "Generated Serializer class "
+                + getFullyQualifiedSerializerClassName(beanType));
+    }
+
+    private void writeEnumDeserializer(TreeLogger logger,
+            SourceWriter sourceWriter, JEnumType enumType) {
+        sourceWriter.println("String enumIdentifier = (("
+                + JSONString.class.getName() + ")jsonValue).stringValue();");
+        for (JEnumConstant e : enumType.getEnumConstants()) {
+            sourceWriter.println("if (\"" + e.getName()
+                    + "\".equals(enumIdentifier)) {");
+            sourceWriter.indent();
+            sourceWriter.println("return " + enumType.getQualifiedSourceName()
+                    + "." + e.getName() + ";");
+            sourceWriter.outdent();
+            sourceWriter.println("}");
+        }
+        sourceWriter.println("return null;");
+    }
+
+    private void writeBeanDeserializer(TreeLogger logger,
+            SourceWriter sourceWriter, JClassType beanType) {
+        String beanQualifiedSourceName = beanType.getQualifiedSourceName();
+
         // if (target == null) {
         sourceWriter.println("if (target == null) {");
         sourceWriter.indent();
+
         // target = GWT.create(VButtonState.class);
         sourceWriter.println("target = GWT.create(" + beanQualifiedSourceName
                 + ".class);");
         sourceWriter.outdent();
         sourceWriter.println("}");
 
+        // JSONOBject json = (JSONObject)jsonValue;
+        sourceWriter.println(JSONObject.class.getName() + " json = ("
+                + JSONObject.class.getName() + ")jsonValue;");
+
         for (JMethod method : getSetters(beanType)) {
             String setterName = method.getName();
             String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
@@ -175,14 +208,14 @@ public class SerializerGenerator extends Generator {
             logger.log(Type.DEBUG, "* Processing field " + fieldName + " in "
                     + beanQualifiedSourceName + " (" + beanType.getName() + ")");
 
-            // if (jsonValue.containsKey("height")) {
-            sourceWriter.println("if (jsonValue.containsKey(\"" + fieldName
+            // if (json.containsKey("height")) {
+            sourceWriter.println("if (json.containsKey(\"" + fieldName
                     + "\")) {");
             sourceWriter.indent();
             String jsonFieldName = "json_" + fieldName;
-            // JSONArray json_Height = (JSONArray) jsonValue.get("height");
+            // JSONArray json_Height = (JSONArray) json.get("height");
             sourceWriter.println("JSONArray " + jsonFieldName
-                    + " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");
+                    + " = (JSONArray) json.get(\"" + fieldName + "\");");
 
             String fieldType;
             String getterName = "get" + fieldName;
@@ -228,17 +261,41 @@ public class SerializerGenerator extends Generator {
 
         // return target;
         sourceWriter.println("return target;");
-        sourceWriter.println("}");
-        sourceWriter.outdent();
 
-        // End of class
-        sourceWriter.println("}");
-        sourceWriter.outdent();
+    }
 
-        // commit generated class
-        context.commit(logger, printWriter);
-        logger.log(TreeLogger.INFO, "Generated Serializer class "
-                + getFullyQualifiedSerializerClassName(beanType));
+    private void writeEnumSerializer(TreeLogger logger,
+            SourceWriter sourceWriter, JClassType beanType) {
+        // return new JSONString(castedValue.name());
+        sourceWriter.println("return new " + JSONString.class.getName()
+                + "(castedValue.name());");
+    }
+
+    private void writeBeanSerializer(TreeLogger logger,
+            SourceWriter sourceWriter, JClassType beanType) {
+
+        // JSONObject json = new JSONObject();
+        sourceWriter.println(JSONObject.class.getName() + " json = new "
+                + JSONObject.class.getName() + "();");
+
+        for (JMethod setterMethod : getSetters(beanType)) {
+            String setterName = setterMethod.getName();
+            String fieldName = setterName.substring(3); // setZIndex() -> ZIndex
+            String getterName = findGetter(beanType, setterMethod);
+
+            if (getterName == null) {
+                logger.log(TreeLogger.ERROR, "No getter found for " + fieldName
+                        + ". Serialization will likely fail");
+            }
+            // json.put("button",
+            // JsonEncoder.encode(castedValue.getButton(), idMapper,
+            // connection));
+            sourceWriter.println("json.put(\"" + fieldName + "\", "
+                    + JsonEncoder.class.getName() + ".encode(castedValue."
+                    + getterName + "(), idMapper, connection));");
+        }
+        // return json;
+        sourceWriter.println("return json;");
 
     }
 
@@ -283,10 +340,6 @@ public class SerializerGenerator extends Generator {
         return setterMethods;
     }
 
-    private String decapitalize(String name) {
-        return name.substring(0, 1).toLowerCase() + name.substring(1);
-    }
-
     private static String getSerializerSimpleClassName(JClassType beanType) {
         return getSimpleClassName(beanType) + "_Serializer";
     }
index 013df4710caa999d36eece1e3a402ae29439c20b..07efcda91baaff92157a418a1aced479201a0920 100644 (file)
@@ -301,9 +301,6 @@ public class SerializerMapGenerator extends Generator {
         if (setterType.isArray() != null) {
             return true;
         }
-        if (setterType.isEnum() != null) {
-            return true;
-        }
         if (setterType.isPrimitive() != null) {
             return true;
         }