svn changeset:13669/svn branch:6.4tags/6.7.0.beta1
@@ -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> | |||
@@ -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; |
@@ -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(); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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("}"); | |||
} | |||
/** |
@@ -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; | |||
@@ -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(); | |||