svn changeset:13669/svn branch:6.4tags/6.7.0.beta1
</replace-with> | </replace-with> | ||||
<generate-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" /> | <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" /> | ||||
</generate-with> | </generate-with> | ||||
return VWindow.class; | return VWindow.class; | ||||
} else if (widgetClass == VFilterSelect.class) { | } else if (widgetClass == VFilterSelect.class) { | ||||
if (uidl.hasAttribute("type")) { | 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(); | final String type = uidl.getStringAttribute("type").intern(); | ||||
if (type == "twincol") { | if (type == "twincol") { | ||||
return VTwinColSelect.class; | return VTwinColSelect.class; |
/* | |||||
@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(); | |||||
} |
/* | |||||
@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; | |||||
} | |||||
} |
/* | |||||
@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; | |||||
} | |||||
} |
package com.vaadin.terminal.gwt.widgetsetutils; | package com.vaadin.terminal.gwt.widgetsetutils; | ||||
import java.io.PrintWriter; | import java.io.PrintWriter; | ||||
import java.util.ArrayList; | |||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import com.vaadin.ui.ClientWidget.LoadStyle; | 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 { | public class WidgetMapGenerator extends Generator { | ||||
sourceWriter.println("if(!instmap.containsKey(classType)){"); | sourceWriter.println("if(!instmap.containsKey(classType)){"); | ||||
boolean first = true; | boolean first = true; | ||||
ArrayList<Class<? extends Paintable>> lazyLoadedWidgets = new ArrayList<Class<? extends Paintable>>(); | |||||
for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) { | for (Class<? extends Paintable> class1 : paintablesHavingWidgetAnnotation) { | ||||
ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | ClientWidget annotation = class1.getAnnotation(ClientWidget.class); | ||||
Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation | Class<? extends com.vaadin.terminal.gwt.client.Paintable> clientClass = annotation | ||||
+ clientClass.getName() | + clientClass.getName() | ||||
+ ".class," | + ".class," | ||||
+ instantiator + ");}});\n"); | + instantiator + ");}});\n"); | ||||
lazyLoadedWidgets.add(class1); | |||||
if (loadStyle == LoadStyle.DEFERRED) { | if (loadStyle == LoadStyle.DEFERRED) { | ||||
deferredWidgets.add(class1); | deferredWidgets.add(class1); | ||||
sourceWriter.println("};"); | sourceWriter.println("};"); | ||||
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("}"); | |||||
} | } | ||||
/** | /** |
import java.lang.annotation.Target; | import java.lang.annotation.Target; | ||||
import com.vaadin.terminal.gwt.client.Paintable; | 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; | import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator; | ||||
/** | /** | ||||
* With this annotation server side Vaadin component is marked to have a client | * 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 | * side counterpart. The value of the annotation is the class of client side | ||||
* implementation. | * implementation. | ||||
* | |||||
* <p> | * <p> | ||||
* Note, even though client side implementation is needed during development, | * 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 | * @since 6.2 | ||||
*/ | */ | ||||
Class<? extends Paintable> value(); | 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> | * <p> | ||||
* Lazy loaded widgets don't stress the size and startup time of the client | * 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 | * 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 | * slight latency when lazy loaded widgets are first used as the client side | ||||
* needs to visit the server to fetch the client side implementation. | * needs to visit the server to fetch the client side implementation. | ||||
* <p> | * <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> | * <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; | LoadStyle loadStyle() default LoadStyle.DEFERRED; | ||||
import com.vaadin.event.dd.DropHandler; | import com.vaadin.event.dd.DropHandler; | ||||
import com.vaadin.event.dd.acceptcriteria.AcceptAll; | import com.vaadin.event.dd.acceptcriteria.AcceptAll; | ||||
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; | 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.Not; | ||||
import com.vaadin.event.dd.acceptcriteria.SourceIsTarget; | |||||
import com.vaadin.terminal.ApplicationResource; | import com.vaadin.terminal.ApplicationResource; | ||||
import com.vaadin.terminal.Resource; | import com.vaadin.terminal.Resource; | ||||
import com.vaadin.terminal.StreamResource; | import com.vaadin.terminal.StreamResource; | ||||
WrapperTargetDetails dropTargetDetails = (WrapperTargetDetails) dropEvent | WrapperTargetDetails dropTargetDetails = (WrapperTargetDetails) dropEvent | ||||
.getTargetDetails(); | .getTargetDetails(); | ||||
MouseEventDetails mouseEvent = dropTargetDetails | MouseEventDetails mouseEvent = dropTargetDetails | ||||
.getMouseEvent(); | .getMouseEvent(); | ||||