]> source.dussan.org Git - vaadin-framework.git/commitdiff
#8304 Generator for Serializers
authorArtur Signell <artur@vaadin.com>
Tue, 21 Feb 2012 16:23:24 +0000 (18:23 +0200)
committerArtur Signell <artur@vaadin.com>
Tue, 21 Feb 2012 16:23:24 +0000 (18:23 +0200)
src/com/vaadin/terminal/gwt/client/ComponentState_Serializer.java [deleted file]
src/com/vaadin/terminal/gwt/client/ui/VButtonState_Serializer.java [deleted file]
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java

diff --git a/src/com/vaadin/terminal/gwt/client/ComponentState_Serializer.java b/src/com/vaadin/terminal/gwt/client/ComponentState_Serializer.java
deleted file mode 100644 (file)
index 075b7f9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.vaadin.terminal.gwt.client;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.json.client.JSONArray;\r
-import com.google.gwt.json.client.JSONObject;\r
-import com.vaadin.terminal.gwt.client.communication.JsonDecoder;\r
-import com.vaadin.terminal.gwt.client.communication.VaadinSerializer;\r
-\r
-//TODO This should be autogenerated\r
-public class ComponentState_Serializer implements VaadinSerializer {\r
-\r
-    public ComponentState deserialize(JSONObject jsonValue,\r
-            VPaintableMap idMapper) {\r
-        ComponentState state = GWT.create(ComponentState.class);\r
-\r
-        // For (Field f : fields) {\r
-        // state.setState((Map<String, Object>)\r
-        // JsonDecoder.convertMap(jsonValue,\r
-        // idMapper));\r
-        JSONArray jsonHeight = (JSONArray) jsonValue.get("height");\r
-        state.setHeight((String) JsonDecoder.convertValue(jsonHeight, idMapper));\r
-\r
-        JSONArray jsonWidth = (JSONArray) jsonValue.get("width");\r
-        state.setWidth((String) JsonDecoder.convertValue(jsonWidth, idMapper));\r
-\r
-        return state;\r
-    }\r
-}\r
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButtonState_Serializer.java b/src/com/vaadin/terminal/gwt/client/ui/VButtonState_Serializer.java
deleted file mode 100644 (file)
index 31cb9ab..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.vaadin.terminal.gwt.client.ui;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.json.client.JSONArray;\r
-import com.google.gwt.json.client.JSONObject;\r
-import com.vaadin.terminal.gwt.client.VPaintableMap;\r
-import com.vaadin.terminal.gwt.client.communication.JsonDecoder;\r
-import com.vaadin.terminal.gwt.client.communication.VaadinSerializer;\r
-\r
-//TODO This should be autogenerated\r
-public class VButtonState_Serializer implements VaadinSerializer {\r
-\r
-    public VButtonState deserialize(JSONObject jsonValue, VPaintableMap idMapper) {\r
-        VButtonState state = GWT.create(VButtonState.class);\r
-\r
-        JSONArray jsonHeight = (JSONArray) jsonValue.get("height");\r
-        state.setHeight((String) JsonDecoder.convertValue(jsonHeight, idMapper));\r
-\r
-        JSONArray jsonWidth = (JSONArray) jsonValue.get("width");\r
-        state.setWidth((String) JsonDecoder.convertValue(jsonWidth, idMapper));\r
-\r
-        JSONArray jsonDisableOnClick = (JSONArray) jsonValue\r
-                .get("disableOnClick");\r
-        state.setDisableOnClick((Boolean) JsonDecoder.convertValue(\r
-                jsonDisableOnClick, idMapper));\r
-\r
-        JSONArray jsonClickShortcutKeyCode = (JSONArray) jsonValue\r
-                .get("clickShortcutKeyCode");\r
-        state.setClickShortcutKeyCode((Integer) JsonDecoder.convertValue(\r
-                jsonClickShortcutKeyCode, idMapper));\r
-\r
-        return state;\r
-    }\r
-}\r
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerGenerator.java
new file mode 100644 (file)
index 0000000..1cd156e
--- /dev/null
@@ -0,0 +1,161 @@
+package com.vaadin.terminal.gwt.widgetsetutils;\r
+\r
+import java.io.PrintWriter;\r
+import java.util.Date;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.ext.Generator;\r
+import com.google.gwt.core.ext.GeneratorContext;\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.TreeLogger.Type;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JClassType;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;\r
+import com.google.gwt.core.ext.typeinfo.JType;\r
+import com.google.gwt.core.ext.typeinfo.TypeOracle;\r
+import com.google.gwt.json.client.JSONArray;\r
+import com.google.gwt.json.client.JSONObject;\r
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+import com.vaadin.terminal.gwt.client.VPaintableMap;\r
+import com.vaadin.terminal.gwt.client.communication.JsonDecoder;\r
+import com.vaadin.terminal.gwt.client.communication.VaadinSerializer;\r
+\r
+public class SerializerGenerator extends Generator {\r
+\r
+    private String packageName;\r
+    private String beanSerializerClassName;\r
+\r
+    @Override\r
+    public String generate(TreeLogger logger, GeneratorContext context,\r
+            String beanTypeName) throws UnableToCompleteException {\r
+        String beanSerializerTypeName = beanTypeName + "_Serializer";\r
+        try {\r
+            TypeOracle typeOracle = context.getTypeOracle();\r
+\r
+            // get classType and save instance variables\r
+            JClassType classType = typeOracle.getType(beanTypeName);\r
+            packageName = classType.getPackage().getName();\r
+            beanSerializerClassName = classType.getSimpleSourceName()\r
+                    + "_Serializer";\r
+            // Generate class source code\r
+            generateClass(logger, context, beanTypeName, beanSerializerTypeName);\r
+        } catch (Exception e) {\r
+            logger.log(TreeLogger.ERROR, "SerializerGenerator failed for "\r
+                    + beanTypeName, e);\r
+        }\r
+        // return the fully qualifed name of the class generated\r
+        return packageName + "." + beanSerializerClassName;\r
+    }\r
+\r
+    /**\r
+     * Generate source code for WidgetMapImpl\r
+     * \r
+     * @param logger\r
+     *            Logger object\r
+     * @param context\r
+     *            Generator context\r
+     * @param typeName\r
+     */\r
+    private void generateClass(TreeLogger logger, GeneratorContext context,\r
+            String beanTypeName, String beanSerializerTypeName) {\r
+        // get print writer that receives the source code\r
+        PrintWriter printWriter = null;\r
+        printWriter = context.tryCreate(logger, packageName,\r
+                beanSerializerClassName);\r
+\r
+        // print writer if null, source code has ALREADY been generated\r
+        if (printWriter == null) {\r
+            return;\r
+        }\r
+        Date date = new Date();\r
+        TypeOracle typeOracle = context.getTypeOracle();\r
+        logger.log(Type.DEBUG, "Processing serializable type " + beanTypeName\r
+                + "...");\r
+\r
+        // init composer, set class properties, create source writer\r
+        ClassSourceFileComposerFactory composer = null;\r
+        composer = new ClassSourceFileComposerFactory(packageName,\r
+                beanSerializerClassName);\r
+        composer.addImport(GWT.class.getName());\r
+        composer.addImport(JSONArray.class.getName());\r
+        // composer.addImport(JSONObject.class.getName());\r
+        // composer.addImport(VPaintableMap.class.getName());\r
+        composer.addImport(JsonDecoder.class.getName());\r
+        // composer.addImport(VaadinSerializer.class.getName());\r
+\r
+        composer.addImplementedInterface(VaadinSerializer.class.getName());\r
+\r
+        SourceWriter sourceWriter = composer.createSourceWriter(context,\r
+                printWriter);\r
+        sourceWriter.indent();\r
+\r
+        sourceWriter.println("public " + beanTypeName + " deserialize("\r
+                + JSONObject.class.getName() + " jsonValue, "\r
+                + VPaintableMap.class.getName() + " idMapper) {");\r
+        sourceWriter.indent();\r
+\r
+        // VButtonState state = GWT.create(VButtonState.class);\r
+        sourceWriter.println(beanTypeName + " state = GWT.create("\r
+                + beanTypeName + ".class);");\r
+        JClassType beanType = typeOracle.findType(beanTypeName);\r
+        for (JMethod method : beanType.getMethods()) {\r
+            // Process all setters that have corresponding fields\r
+            if (!method.isPublic() || method.isStatic()\r
+                    || !method.getName().startsWith("set")\r
+                    || method.getParameterTypes().length != 1) {\r
+                // Not setter, skip to next method\r
+                continue;\r
+\r
+            }\r
+            String setterName = method.getName();\r
+            String capitalizedFieldName = setterName.substring(3);\r
+            String fieldName = decapitalize(capitalizedFieldName);\r
+            JType setterParameterType = method.getParameterTypes()[0];\r
+\r
+            logger.log(Type.DEBUG, "* Processing field " + fieldName + " in "\r
+                    + beanTypeName);\r
+\r
+            String jsonFieldName = "json" + capitalizedFieldName;\r
+            // JSONArray jsonHeight = (JSONArray) jsonValue.get("height");\r
+            sourceWriter.println("JSONArray " + jsonFieldName\r
+                    + " = (JSONArray) jsonValue.get(\"" + fieldName + "\");");\r
+            // state.setHeight((String)\r
+            // JsonDecoder.convertValue(jsonFieldValue,idMapper));\r
+\r
+            String fieldType;\r
+            JPrimitiveType primitiveType = setterParameterType.isPrimitive();\r
+            if (primitiveType != null) {\r
+                // This is a primitive type -> must used the boxed type\r
+                fieldType = primitiveType.getQualifiedBoxedSourceName();\r
+            } else {\r
+                fieldType = setterParameterType.getQualifiedSourceName();\r
+            }\r
+\r
+            sourceWriter.println("state." + setterName + "((" + fieldType\r
+                    + ") JsonDecoder.convertValue(" + jsonFieldName\r
+                    + ", idMapper));");\r
+        }\r
+\r
+        // return state;\r
+        sourceWriter.println("return state;");\r
+        sourceWriter.println("}");\r
+        sourceWriter.outdent();\r
+\r
+        // End of class\r
+        sourceWriter.println("}");\r
+        sourceWriter.outdent();\r
+\r
+        // commit generated class\r
+        context.commit(logger, printWriter);\r
+        logger.log(Type.INFO,\r
+                "Done. (" + (new Date().getTime() - date.getTime()) / 1000\r
+                        + "seconds)");\r
+\r
+    }\r
+\r
+    private String decapitalize(String name) {\r
+        return name.substring(0, 1).toLowerCase() + name.substring(1);\r
+    }\r
+}\r
index 651ae24b2dd4f94e1234c9aa11d5bc8fa3b100e2..2fabf8bd719da28f07cd4c7c4196c7ff4c9472a5 100644 (file)
@@ -34,8 +34,17 @@ public class SerializerMapGenerator extends Generator {
             className = classType.getSimpleSourceName() + "Impl";\r
             // Generate class source code\r
             generateClass(logger, context);\r
+\r
+            JClassType serializerType = typeOracle.findType(SharedState.class\r
+                    .getName());\r
+            JClassType[] serializerSubtypes = serializerType.getSubtypes();\r
+            SerializerGenerator sg = new SerializerGenerator();\r
+            for (JClassType type : serializerSubtypes) {\r
+                sg.generate(logger, context, type.getQualifiedSourceName());\r
+            }\r
         } catch (Exception e) {\r
-            logger.log(TreeLogger.ERROR, "WidgetMap creation failed", e);\r
+            logger.log(TreeLogger.ERROR,\r
+                    "SerializerMapGenerator creation failed", e);\r
         }\r
         // return the fully qualifed name of the class generated\r
         return packageName + "." + className;\r