Browse Source

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
tags/6.7.0.beta1
Matti Tahvonen 14 years ago
parent
commit
8231bc935b

+ 1
- 1
src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml View 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>


+ 1
- 1
src/com/vaadin/terminal/gwt/client/WidgetSet.java View 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;

+ 83
- 0
src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java View File

@@ -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();

}

+ 28
- 0
src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java View File

@@ -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;
}
}

+ 23
- 0
src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java View File

@@ -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;
}

}

+ 58
- 2
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java View 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("}");

}

/**

+ 31
- 21
src/com/vaadin/ui/ClientWidget.java View 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;


+ 2
- 1
tests/src/com/vaadin/tests/dd/DDTest6.java View 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();


Loading…
Cancel
Save