diff options
author | Matti Tahvonen <matti.tahvonen@itmill.com> | 2010-06-15 12:38:24 +0000 |
---|---|---|
committer | Matti Tahvonen <matti.tahvonen@itmill.com> | 2010-06-15 12:38:24 +0000 |
commit | 8231bc935b39eca35415fdb782ed9189b1cfdfa0 (patch) | |
tree | 2cff4ebd3ef5ea0f9192b132989a2eeb96cbe3d6 | |
parent | 3b32d8b9ddbe98fd110f9477922729bd4d5444d4 (diff) | |
download | vaadin-framework-8231bc935b39eca35415fdb782ed9189b1cfdfa0.tar.gz vaadin-framework-8231bc935b39eca35415fdb782ed9189b1cfdfa0.zip |
refining code splitting + adding documentation. Monolithic client side is now default (6.3 style), but the package includes other generator strategies that can be thrown in for custom requirements.
svn changeset:13669/svn branch:6.4
8 files changed, 227 insertions, 26 deletions
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml index 1413377717..c7809cfffe 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -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> diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index d5375114b5..33638b54f3 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -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 index 0000000000..e67a429ee3 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java @@ -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 index 0000000000..a5d1963a5f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java @@ -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 index 0000000000..b3fd921e2f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java @@ -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; + } + +} diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java index 4da8c0a925..b4e5df316c 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -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> + * <generate-with + * class="com.vaadin.terminal.gwt.widgetsetutils.MyWidgetMapGenerator"> + * <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" /> + * </generate-with> + * + * </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("}"); + } /** diff --git a/src/com/vaadin/ui/ClientWidget.java b/src/com/vaadin/ui/ClientWidget.java index 0848309b31..1bfe58da66 100644 --- a/src/com/vaadin/ui/ClientWidget.java +++ b/src/com/vaadin/ui/ClientWidget.java @@ -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; diff --git a/tests/src/com/vaadin/tests/dd/DDTest6.java b/tests/src/com/vaadin/tests/dd/DDTest6.java index 74a7e39db1..39e5a3e355 100644 --- a/tests/src/com/vaadin/tests/dd/DDTest6.java +++ b/tests/src/com/vaadin/tests/dd/DDTest6.java @@ -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(); |