]> source.dussan.org Git - vaadin-framework.git/commitdiff
refining code splitting + adding documentation. Monolithic client side is now default...
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 15 Jun 2010 12:38:24 +0000 (12:38 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Tue, 15 Jun 2010 12:38:24 +0000 (12:38 +0000)
svn changeset:13669/svn branch:6.4

src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
src/com/vaadin/terminal/gwt/client/WidgetSet.java
src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java
src/com/vaadin/ui/ClientWidget.java
tests/src/com/vaadin/tests/dd/DDTest6.java

index 141337771737afa5c420ae6173f2ae250c468004..c7809cfffe86a77af4183eb420987bec72c95546 100644 (file)
@@ -30,7 +30,7 @@
        </replace-with>
 
        <generate-with
-               class="com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator">
+               class="com.vaadin.terminal.gwt.widgetsetutils.EagerWidgetMapGenerator">
                <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" />
        </generate-with>
 
index d5375114b5a182872d38e3891a9d4a6a00ca6af8..33638b54f3a77824e7108fcccd276d4030b1138a 100644 (file)
@@ -96,7 +96,7 @@ public class WidgetSet {
             return VWindow.class;
         } else if (widgetClass == VFilterSelect.class) {
             if (uidl.hasAttribute("type")) {
-                // TODO check if all type checks are really neede
+                // TODO check if all type checks are really needed
                 final String type = uidl.getStringAttribute("type").intern();
                 if (type == "twincol") {
                     return VTwinColSelect.class;
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java
new file mode 100644 (file)
index 0000000..e67a429
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.widgetsetutils;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import com.vaadin.terminal.Paintable;
+import com.vaadin.ui.ClientWidget;
+import com.vaadin.ui.ClientWidget.LoadStyle;
+
+/**
+ * An abstract helper class that can be used to easily build a widgetset with
+ * customized load styles for each components. In three abstract methods one can
+ * override the default values given in {@link ClientWidget} annotations.
+ * 
+ * @see WidgetMapGenerator
+ * 
+ */
+public abstract class CustomWidgetMapGenerator extends WidgetMapGenerator {
+
+    private Collection<Class<? extends Paintable>> eagerPaintables = new HashSet<Class<? extends Paintable>>();
+    private Collection<Class<? extends Paintable>> lazyPaintables = new HashSet<Class<? extends Paintable>>();
+    private Collection<Class<? extends Paintable>> deferredPaintables = new HashSet<Class<? extends Paintable>>();
+
+    @Override
+    protected LoadStyle getLoadStyle(Class<? extends Paintable> paintableType) {
+        if (eagerPaintables == null) {
+            init();
+        }
+        if (eagerPaintables.contains(paintableType)) {
+            return LoadStyle.EAGER;
+        }
+        if (lazyPaintables.contains(paintableType)) {
+            return LoadStyle.LAZY;
+        }
+        if (deferredPaintables.contains(paintableType)) {
+            return LoadStyle.DEFERRED;
+        }
+        return super.getLoadStyle(paintableType);
+    }
+
+    private void init() {
+        Class<? extends Paintable>[] eagerComponents = getEagerComponents();
+        if (eagerComponents != null) {
+            for (Class<? extends Paintable> class1 : eagerComponents) {
+                eagerPaintables.add(class1);
+            }
+        }
+        Class<? extends Paintable>[] lazyComponents = getEagerComponents();
+        if (lazyComponents != null) {
+            for (Class<? extends Paintable> class1 : lazyComponents) {
+                lazyPaintables.add(class1);
+            }
+        }
+        Class<? extends Paintable>[] deferredComponents = getEagerComponents();
+        if (deferredComponents != null) {
+            for (Class<? extends Paintable> class1 : deferredComponents) {
+                deferredPaintables.add(class1);
+            }
+        }
+    }
+
+    /**
+     * @return an array of components whose load style should be overridden to
+     *         {@link LoadStyle#EAGER}
+     */
+    protected abstract Class<? extends Paintable>[] getEagerComponents();
+
+    /**
+     * @return an array of components whose load style should be overridden to
+     *         {@link LoadStyle#LAZY}
+     */
+    protected abstract Class<? extends Paintable>[] getLazyComponents();
+
+    /**
+     * @return an array of components whose load style should be overridden to
+     *         {@link LoadStyle#DEFERRED}
+     */
+    protected abstract Class<? extends Paintable>[] getDeferredComponents();
+
+}
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java
new file mode 100644 (file)
index 0000000..a5d1963
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.widgetsetutils;
+
+import com.vaadin.terminal.Paintable;
+import com.vaadin.ui.ClientWidget.LoadStyle;
+
+/**
+ * WidgetMap generator that builds a widgetset that packs all included widgets
+ * into a single JavaScript file loaded at application initialization. Initially
+ * loaded data will be relatively large, but minimal amount of server requests
+ * will be done.
+ * <p>
+ * This is the default generator in version 6.4 and produces similar type of
+ * widgetset as in previous versions of Vaadin. To activate "code splitting",
+ * use the {@link WidgetMapGenerator} instead, that loads most components
+ * deferred.
+ * 
+ * @see WidgetMapGenerator
+ * 
+ */
+public class EagerWidgetMapGenerator extends WidgetMapGenerator {
+    @Override
+    protected LoadStyle getLoadStyle(Class<? extends Paintable> paintableType) {
+        return LoadStyle.EAGER;
+    }
+}
diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java
new file mode 100644 (file)
index 0000000..b3fd921
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+package com.vaadin.terminal.gwt.widgetsetutils;
+
+import com.vaadin.terminal.Paintable;
+import com.vaadin.ui.ClientWidget.LoadStyle;
+
+/**
+ * WidgetMap generator that builds a widgetset that optimizes the transferred
+ * data. Widgets are loaded only when used if the widgetset is built with this
+ * generator.
+ * 
+ * @see WidgetMapGenerator
+ * 
+ */
+public class LazyWidgetMapGenerator extends WidgetMapGenerator {
+    @Override
+    protected LoadStyle getLoadStyle(Class<? extends Paintable> paintableType) {
+        return LoadStyle.LAZY;
+    }
+
+}
index 4da8c0a9251da09ec9dfd26c21ac41232b4ef550..b4e5df316c3425651ba20ce468cabb84d96d8ca6 100644 (file)
@@ -4,6 +4,7 @@
 package com.vaadin.terminal.gwt.widgetsetutils;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
@@ -25,8 +26,43 @@ import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 
 /**
- * GWT generator to build WidgetMapImpl dynamically based on
- * {@link ClientWidget} annotations available in workspace.
+ * WidgetMapGenerator's are GWT generator to build WidgetMapImpl dynamically
+ * based on {@link ClientWidget} annotations available in workspace. By
+ * modifying the generator it is possible to do some fine tuning for the
+ * generated widgetset (aka client side engine). The components to be included
+ * in the client side engine can modified be overriding
+ * {@link #getUsedPaintables()}.
+ * <p>
+ * The generator also decides how the client side component implementations are
+ * loaded to the browser. The default generator is
+ * {@link EagerWidgetMapGenerator} that builds a monolithic client side engine
+ * that loads all widget implementation on application initialization. This has
+ * been the only option until Vaadin 6.4.
+ * <p>
+ * This generator uses the loadStyle hints from the {@link ClientWidget}
+ * annotations. Depending on the {@link LoadStyle} used, the widget may be
+ * included in the initially loaded JavaScript, loaded when the application has
+ * started and there is no communication to server or lazy loaded when the
+ * implementation is absolutely needed.
+ * <p>
+ * The GWT module description file of the widgetset (
+ * <code>...Widgetset.gwt.xml</code>) can be used to define the
+ * WidgetMapGenarator. An example that defines this generator to be used:
+ * 
+ * <pre>
+ * <code>
+ * &lt;generate-with
+ *           class="com.vaadin.terminal.gwt.widgetsetutils.MyWidgetMapGenerator"&gt;
+ *          &lt;when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" /&gt;
+ * &lt;/generate-with&gt;
+ * 
+ * </code>
+ * </pre>
+ * 
+ * <p>
+ * Vaadin package also includes {@link LazyWidgetMapGenerator}, which is a good
+ * option if the transferred data should be minimized, and
+ * {@link CustomWidgetMapGenerator} for easy overriding of loading strategies.
  * 
  */
 public class WidgetMapGenerator extends Generator {
@@ -195,6 +231,7 @@ public class WidgetMapGenerator extends Generator {
         sourceWriter.println("if(!instmap.containsKey(classType)){");
         boolean first = true;
 
+        ArrayList<Class<? extends Paintable>> lazyLoadedWidgets = new ArrayList<Class<? extends Paintable>>();
         for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) {
             ClientWidget annotation = class1.getAnnotation(ClientWidget.class);
             Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation
@@ -224,6 +261,7 @@ public class WidgetMapGenerator extends Generator {
                                 + clientClass.getName()
                                 + ".class,"
                                 + instantiator + ");}});\n");
+                lazyLoadedWidgets.add(class1);
 
                 if (loadStyle == LoadStyle.DEFERRED) {
                     deferredWidgets.add(class1);
@@ -262,6 +300,24 @@ public class WidgetMapGenerator extends Generator {
 
         sourceWriter.println("};");
         sourceWriter.println("}");
+
+        // in constructor add a "thread" that lazyly loads lazy loaded widgets
+        // if communication to server idles
+
+        // TODO an array of lazy loaded widgets
+
+        // TODO an index of last ensured widget in array
+
+        sourceWriter
+                .println("public Paintable instantiate(Class<? extends Paintable> classType) {");
+        sourceWriter.indent();
+        sourceWriter
+                .println("Paintable p = super.instantiate(classType); if(p!= null) return p;");
+        sourceWriter.println("return instmap.get(classType).get();");
+
+        sourceWriter.outdent();
+        sourceWriter.println("}");
+
     }
 
     /**
index 0848309b3107b555fd75acf0aa40d7a32a3ec586..1bfe58da661d14a34e2718f301fbd02c2c4ed2f8 100644 (file)
@@ -12,6 +12,9 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.widgetsetutils.CustomWidgetMapGenerator;
+import com.vaadin.terminal.gwt.widgetsetutils.EagerWidgetMapGenerator;
+import com.vaadin.terminal.gwt.widgetsetutils.LazyWidgetMapGenerator;
 import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator;
 
 /**
@@ -21,10 +24,9 @@ import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator;
  * With this annotation server side Vaadin component is marked to have a client
  * side counterpart. The value of the annotation is the class of client side
  * implementation.
- * 
  * <p>
  * Note, even though client side implementation is needed during development,
- * one may safely remove them from classpath of the production server.
+ * one may safely remove them from the classpath of the production server.
  * 
  * @since 6.2
  */
@@ -37,33 +39,41 @@ public @interface ClientWidget {
     Class<? extends Paintable> value();
 
     /**
-     * TODO rewrite for EAGER, DEFERRED, LAZY
-     * 
-     * The lazy loading of a widget implementation means the client side
-     * component is not included in the initial JavaScript application loaded
-     * when the application starts. Instead the implementation is loaded to the
-     * client when it is first needed.
+     * Depending on the used WidgetMap generator, these optional hints may be
+     * used to define how the client side components are loaded by the browser.
+     * The default is to eagerly load all widgets
+     * {@link EagerWidgetMapGenerator}, but if the {@link WidgetMapGenerator} is
+     * used by the widgetset, these load style hints are respected.
+     * <p>
+     * Lazy loading of a widget implementation means the client side component
+     * is not included in the initial JavaScript application loaded when the
+     * application starts. Instead the implementation is loaded to the client
+     * when it is first needed. Lazy loaded widget can be achieved by giving
+     * {@link LoadStyle#LAZY} value in ClientWidget annotation.
      * <p>
      * Lazy loaded widgets don't stress the size and startup time of the client
      * side as much as eagerly loaded widgets. On the other hand there is a
      * slight latency when lazy loaded widgets are first used as the client side
      * needs to visit the server to fetch the client side implementation.
      * <p>
-     * In common situations the default value should be fine. If the widget
-     * implementation commonly used and often on first view it is better set
-     * lazy loading off for it. Also if the component implementation is really
-     * thing, it may by justified to make the widget implementation eagerly
-     * loaded.
+     * The {@link LoadStyle#DEFERRED} will also not stress the initially loaded
+     * JavaScript file. If this load style is defined, the widget implementation
+     * is preemptively loaded to the browser after the application is started
+     * and the communication to server idles. This load style kind of combines
+     * the best of both worlds.
      * <p>
-     * Tunings to widget loading can also be made by overriding
-     * {@link WidgetMapGenerator} in GWT module. Tunings might be helpful if the
-     * end users have slow connections and especially if they have high latency
-     * in their network.
+     * Fine tunings to widget loading can also be made by overriding
+     * {@link WidgetMapGenerator} in the GWT module. Tunings might be helpful if
+     * the end users have slow connections and especially if they have high
+     * latency in their network. The {@link CustomWidgetMapGenerator} is an
+     * abstract generator implementation for easy customization. Vaadin package
+     * also includes {@link LazyWidgetMapGenerator} that makes as many widgets
+     * lazily loaded as possible.
+     * 
+     * @since 6.4
      * 
-     * @return if true (default), the GWT code generator will make the client
-     *         side implementation lazy loaded. Displaying it first time on the
-     *         screen slightly increases, but widgets implementation does not
-     *         stress the initialization of the client side engine.
+     * @return the hint for the widget set generator how the client side
+     *         implementation should be loaded to the browser
      */
     LoadStyle loadStyle() default LoadStyle.DEFERRED;
 
index 74a7e39db13b9a23c02fcd8fac45fe0ae65dfede..39e5a3e3551f701dd9d97c4fa5fdd8fee132bb01 100644 (file)
@@ -24,8 +24,8 @@ import com.vaadin.event.dd.DragAndDropEvent;
 import com.vaadin.event.dd.DropHandler;
 import com.vaadin.event.dd.acceptcriteria.AcceptAll;
 import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-import com.vaadin.event.dd.acceptcriteria.SourceIsTarget;
 import com.vaadin.event.dd.acceptcriteria.Not;
+import com.vaadin.event.dd.acceptcriteria.SourceIsTarget;
 import com.vaadin.terminal.ApplicationResource;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.StreamResource;
@@ -371,6 +371,7 @@ public class DDTest6 extends TestBase {
 
                 WrapperTargetDetails dropTargetDetails = (WrapperTargetDetails) dropEvent
                         .getTargetDetails();
+
                 MouseEventDetails mouseEvent = dropTargetDetails
                         .getMouseEvent();