public void paint(PaintTarget target) throws PaintException {
target.startTag("-ac");
- target.addAttribute("name", "acceptAll");
+ target.addAttribute("name", getClass().getCanonicalName());
target.endTag("-ac");
}
public void paint(PaintTarget target) throws PaintException {
target.startTag("-ac");
- target.addAttribute("name", "and");
+ target.addAttribute("name", getClass().getCanonicalName());
(f1).paint(target);
(f2).paint(target);
target.endTag("-ac");
public void paint(PaintTarget target) throws PaintException {
target.startTag("-ac");
- target.addAttribute("name", "component");
+ target.addAttribute("name", getClass().getCanonicalName());
target.addAttribute("component", component);
target.endTag("-ac");
}
public void paint(PaintTarget target) throws PaintException {
target.startTag("-ac");
- target.addAttribute("name", "needsItemId");
+ target.addAttribute("name", getClass().getCanonicalName());
target.endTag("-ac");
}
public void paint(PaintTarget target) throws PaintException {
target.startTag("-ac");
- target.addAttribute("name", "overTreeNode");
+ target.addAttribute("name", getClass().getCanonicalName());
target.endTag("-ac");
}
}
protected String getIdentifier() {
- return "-ss";
+ return ServerSideCriterion.class.getCanonicalName();
}
}
<when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap"/>
</generate-with>
+ <generate-with class="com.vaadin.terminal.gwt.widgetsetutils.AcceptCriterionGenerator">
+ <when-type-is class="com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterionFactory"/>
+ </generate-with>
+
+
<entry-point class="com.vaadin.terminal.gwt.client.DefaultWidgetSet" />
</module>
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.AcceptAll")
+final class AcceptAll implements VAcceptCriteria {
+ public void accept(VDragEvent drag, UIDL configuration,
+ VAcceptCallback callback) {
+ callback.accepted(drag);
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.And")
+final class And implements VAcceptCriteria {
+ private boolean b1;
+ private boolean b2;
+ private VAcceptCriteria crit1;
+ private VAcceptCriteria crit2;
+
+ public void accept(VDragEvent drag, UIDL configuration,
+ VAcceptCallback callback) {
+ if (crit1 == null) {
+ crit1 = getCriteria(drag, configuration, 0);
+ crit2 = getCriteria(drag, configuration, 1);
+ if (crit1 == null || crit2 == null) {
+ ApplicationConnection.getConsole().log(
+ "And criteria didn't found a chidl criteria");
+ return;
+ }
+ }
+
+ b1 = false;
+ b2 = false;
+
+ VAcceptCallback accept1cb = new VAcceptCallback() {
+ public void accepted(VDragEvent event) {
+ b1 = true;
+ }
+ };
+ VAcceptCallback accept2cb = new VAcceptCallback() {
+ public void accepted(VDragEvent event) {
+ b2 = true;
+ }
+ };
+
+ crit1.accept(drag, configuration.getChildUIDL(0), accept1cb);
+ crit2.accept(drag, configuration.getChildUIDL(0), accept2cb);
+ if (b1 && b2) {
+ callback.accepted(drag);
+ }
+ }
+
+ private VAcceptCriteria getCriteria(VDragEvent drag, UIDL configuration,
+ int i) {
+ UIDL childUIDL = configuration.getChildUIDL(i);
+ return VAcceptCriterion.get(childUIDL.getStringAttribute("name"));
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return false; // TODO enforce on server side
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.Paintable;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.ComponentFilter")
+final class ComponentCriteria implements VAcceptCriteria {
+ public void accept(VDragEvent drag, UIDL configuration,
+ VAcceptCallback callback) {
+ try {
+ Paintable component = drag.getTransferable().getComponent();
+ String requiredPid = configuration.getStringAttribute("component");
+ Paintable paintable = VDragAndDropManager.get()
+ .getCurrentDropHandler().getApplicationConnection()
+ .getPaintable(requiredPid);
+ if (paintable == component) {
+ callback.accepted(drag);
+ }
+ } catch (Exception e) {
+ }
+ return;
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.IsDataBinded")
+final class HasItemId implements VAcceptCriteria {
+ public void accept(VDragEvent drag, UIDL configuration,
+ VAcceptCallback callback) {
+ if (drag.getTransferable().getData("itemId") != null) {
+ callback.accepted(drag);
+ }
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import java.util.HashSet;
+
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.ui.Tree.TreeDropCriterion")
+final class LazyInitItemIdentifiers implements VAcceptCriteria {
+ private boolean loaded = false;
+ private HashSet<String> hashSet;
+ private VDragEvent lastDragEvent;
+
+ public void accept(final VDragEvent drag, UIDL configuration,
+ final VAcceptCallback callback) {
+ if (lastDragEvent == null || lastDragEvent != drag) {
+ loaded = false;
+ lastDragEvent = drag;
+ }
+ if (loaded) {
+ Object object = drag.getDropDetails().get("itemIdOver");
+ if (hashSet.contains(object)) {
+ callback.accepted(drag);
+ }
+ } else {
+
+ VDragEventServerCallback acceptCallback = new VDragEventServerCallback() {
+
+ public void handleResponse(boolean accepted, UIDL response) {
+ hashSet = new HashSet<String>();
+ String[] stringArrayAttribute = response
+ .getStringArrayAttribute("allowedIds");
+ for (int i = 0; i < stringArrayAttribute.length; i++) {
+ hashSet.add(stringArrayAttribute[i]);
+ }
+ loaded = true;
+ if (accepted) {
+ callback.accepted(drag);
+ }
+ }
+ };
+
+ VDragAndDropManager.get().visitServer(acceptCallback);
+ }
+
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return loaded;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.OverTreeNode")
+final class OverTreeNode implements VAcceptCriteria {
+ public void accept(VDragEvent drag, UIDL configuration,
+ VAcceptCallback callback) {
+ Boolean containsKey = (Boolean) drag.getDropDetails().get(
+ "itemIdOverIsNode");
+ if (containsKey != null && containsKey.booleanValue()) {
+ callback.accepted(drag);
+ return;
+ }
+ return;
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ *
+ */
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import com.vaadin.terminal.gwt.client.UIDL;
+
+@ServerCriterion("com.vaadin.event.dd.acceptCriteria.ServerSideCriterion")
+final class ServerAccept implements VAcceptCriteria {
+ public void accept(final VDragEvent drag, UIDL configuration,
+ final VAcceptCallback callback) {
+
+ VDragEventServerCallback acceptCallback = new VDragEventServerCallback() {
+ public void handleResponse(boolean accepted, UIDL response) {
+ if (accepted) {
+ callback.accepted(drag);
+ }
+ }
+ };
+ VDragAndDropManager.get().visitServer(acceptCallback);
+ }
+
+ public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ServerCriterion {
+ /**
+ * Class type would be nice but annotating should come from different
+ * direction to cope with gwt compiler.
+ *
+ * @return
+ */
+ String value();
+}
* A class via all AcceptCriteria instances are fetched by an identifier.
*/
public class VAcceptCriterion {
- private static VAcceptCriterionImpl impl;
+ private static VAcceptCriterionFactory impl;
static {
- impl = GWT.create(VAcceptCriterionImpl.class);
- impl.init();
+ impl = GWT.create(VAcceptCriterionFactory.class);
}
public static VAcceptCriteria get(String name) {
--- /dev/null
+package com.vaadin.terminal.gwt.client.ui.dd;
+
+public abstract class VAcceptCriterionFactory {
+
+ public abstract VAcceptCriteria get(String name);
+ // name = name.intern();
+ // // FIXME make all lazy inited and possibility to use instances per
+ // // handler
+ // // TODO maybe just ditch singleton idea and use new instances on each
+ // // fetch for all types of components.
+ // if (name.equals("-ss")) {
+ // return GWT.create(ServerAccept.class);
+ // } else if (name.equals("com.vaadin.ui.Tree.TreeDropCriterion")) {
+ // return GWT.create(LazyInitItemIdentifiers.class);
+ // } else if (name == "needsItemId") {
+ // return GWT.create(HasItemId.class);
+ // } else if (name == "acceptAll") {
+ // return GWT.create(AcceptAll.class);
+ // } else if (name == "and") {
+ // return GWT.create(And.class);
+ // } else if (name == "overTreeNode") {
+ // return GWT.create(OverTreeNode.class);
+ // } else if (name == "component") {
+ // return GWT.create(ComponentCriteria.class);
+ // }
+ // return null;
+ // }
+}
+++ /dev/null
-package com.vaadin.terminal.gwt.client.ui.dd;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VAcceptCriterionImpl {
-
- private final class OverTreeNode implements VAcceptCriteria {
- public void accept(VDragEvent drag, UIDL configuration,
- VAcceptCallback callback) {
- Boolean containsKey = (Boolean) drag.getDropDetails().get(
- "itemIdOverIsNode");
- if (containsKey != null && containsKey.booleanValue()) {
- callback.accepted(drag);
- return;
- }
- return;
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return false;
- }
- }
-
- private final class ComponentCriteria implements VAcceptCriteria {
- public void accept(VDragEvent drag, UIDL configuration,
- VAcceptCallback callback) {
- try {
- Paintable component = drag.getTransferable().getComponent();
- String requiredPid = configuration
- .getStringAttribute("component");
- Paintable paintable = VDragAndDropManager.get()
- .getCurrentDropHandler().getApplicationConnection()
- .getPaintable(requiredPid);
- if (paintable == component) {
- callback.accepted(drag);
- }
- } catch (Exception e) {
- }
- return;
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return false;
- }
- }
-
- private final class And implements VAcceptCriteria {
- private boolean b1;
- private boolean b2;
- private VAcceptCriteria crit1;
- private VAcceptCriteria crit2;
-
- public void accept(VDragEvent drag, UIDL configuration,
- VAcceptCallback callback) {
- if (crit1 == null) {
- crit1 = getCriteria(drag, configuration, 0);
- crit2 = getCriteria(drag, configuration, 1);
- if (crit1 == null || crit2 == null) {
- ApplicationConnection.getConsole().log(
- "And criteria didn't found a chidl criteria");
- return;
- }
- }
-
- b1 = false;
- b2 = false;
-
- VAcceptCallback accept1cb = new VAcceptCallback() {
- public void accepted(VDragEvent event) {
- b1 = true;
- }
- };
- VAcceptCallback accept2cb = new VAcceptCallback() {
- public void accepted(VDragEvent event) {
- b2 = true;
- }
- };
-
- crit1.accept(drag, configuration.getChildUIDL(0), accept1cb);
- crit2.accept(drag, configuration.getChildUIDL(0), accept2cb);
- if (b1 && b2) {
- callback.accepted(drag);
- }
- }
-
- private VAcceptCriteria getCriteria(VDragEvent drag,
- UIDL configuration, int i) {
- UIDL childUIDL = configuration.getChildUIDL(i);
- return VAcceptCriterion.get(childUIDL.getStringAttribute("name"));
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return false; // TODO enforce on server side
- }
- }
-
- private final class AcceptAll implements VAcceptCriteria {
- public void accept(VDragEvent drag, UIDL configuration,
- VAcceptCallback callback) {
- callback.accepted(drag);
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return false;
- }
- }
-
- private final class HasItemId implements VAcceptCriteria {
- public void accept(VDragEvent drag, UIDL configuration,
- VAcceptCallback callback) {
- if (drag.getTransferable().getData("itemId") != null) {
- callback.accepted(drag);
- }
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return false;
- }
- }
-
- private final class ServerAccept implements VAcceptCriteria {
- public void accept(final VDragEvent drag, UIDL configuration,
- final VAcceptCallback callback) {
-
- // TODO could easily cache the response for current drag event
-
- VDragEventServerCallback acceptCallback = new VDragEventServerCallback() {
- public void handleResponse(boolean accepted, UIDL response) {
- if (accepted) {
- callback.accepted(drag);
- }
- }
- };
- VDragAndDropManager.get().visitServer(acceptCallback);
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return true;
- }
- }
-
- private final class LazyInitItemIdentifiers implements VAcceptCriteria {
- private boolean loaded = false;
- private HashSet<String> hashSet;
- private VDragEvent lastDragEvent;
-
- public void accept(final VDragEvent drag, UIDL configuration,
- final VAcceptCallback callback) {
- if (lastDragEvent == null || lastDragEvent != drag) {
- loaded = false;
- lastDragEvent = drag;
- }
- if (loaded) {
- Object object = drag.getDropDetails().get("itemIdOver");
- if (hashSet.contains(object)) {
- callback.accepted(drag);
- }
- } else {
-
- VDragEventServerCallback acceptCallback = new VDragEventServerCallback() {
-
- public void handleResponse(boolean accepted, UIDL response) {
- hashSet = new HashSet<String>();
- String[] stringArrayAttribute = response
- .getStringArrayAttribute("allowedIds");
- for (int i = 0; i < stringArrayAttribute.length; i++) {
- hashSet.add(stringArrayAttribute[i]);
- }
- loaded = true;
- if (accepted) {
- callback.accepted(drag);
- }
- }
- };
-
- VDragAndDropManager.get().visitServer(acceptCallback);
- }
-
- }
-
- public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) {
- return loaded;
- }
- }
-
- private Map<String, VAcceptCriteria> instances = new HashMap<String, VAcceptCriteria>();
-
- /**
- * TODO this class/method must be written by generator
- *
- * TODO move implementations to top level classes.
- *
- * TODO use fully qualified names of server side counterparts as keys
- */
- private void populateCriterionMap(Map<String, VAcceptCriteria> map) {
- VAcceptCriteria crit;
-
- crit = new HasItemId();
- map.put("needsItemId", crit);
-
- crit = new AcceptAll();
- map.put("acceptAll", crit);
-
- crit = new And();
- map.put("and", crit);
-
- crit = new OverTreeNode();
- map.put("overTreeNode", crit);
-
- crit = new ComponentCriteria();
- map.put("component", crit);
-
- }
-
- public void init() {
- populateCriterionMap(instances);
- }
-
- public VAcceptCriteria get(String name) {
- // FIXME make all lazy inited and possibility to use instances per
- // handler
- if (name.equals("-ss")) {
- return new ServerAccept();
- } else if (name.equals("com.vaadin.ui.Tree.TreeDropCriterion")) {
- return new LazyInitItemIdentifiers();
- } else {
- return instances.get(name);
- }
- }
-}
--- /dev/null
+package com.vaadin.terminal.gwt.widgetsetutils;
+
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+
+import com.google.gwt.core.ext.Generator;
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.vaadin.terminal.gwt.client.ui.dd.ServerCriterion;
+import com.vaadin.ui.ClientWidget;
+
+/**
+ * GWT generator to build WidgetMapImpl dynamically based on
+ * {@link ClientWidget} annotations available in workspace.
+ *
+ */
+public class AcceptCriterionGenerator extends Generator {
+
+ private String packageName;
+ private String className;
+
+ @Override
+ public String generate(TreeLogger logger, GeneratorContext context,
+ String typeName) throws UnableToCompleteException {
+
+ try {
+ TypeOracle typeOracle = context.getTypeOracle();
+
+ // get classType and save instance variables
+ JClassType classType = typeOracle.getType(typeName);
+ packageName = classType.getPackage().getName();
+ className = classType.getSimpleSourceName() + "Impl";
+ // Generate class source code
+ generateClass(logger, context);
+ } catch (Exception e) {
+ logger.log(TreeLogger.ERROR,
+ "Accept criterion factory creation failed", e);
+ }
+ // return the fully qualifed name of the class generated
+ return packageName + "." + className;
+ }
+
+ /**
+ * Generate source code for WidgetMapImpl
+ *
+ * @param logger
+ * Logger object
+ * @param context
+ * Generator context
+ */
+ private void generateClass(TreeLogger logger, GeneratorContext context) {
+ // get print writer that receives the source code
+ PrintWriter printWriter = null;
+ printWriter = context.tryCreate(logger, packageName, className);
+ // print writer if null, source code has ALREADY been generated,
+ // return (WidgetMap is equal to all permutations atm)
+ if (printWriter == null) {
+ return;
+ }
+ logger.log(Type.INFO, "Detecting available criteria ...");
+ Date date = new Date();
+
+ // init composer, set class properties, create source writer
+ ClassSourceFileComposerFactory composer = null;
+ composer = new ClassSourceFileComposerFactory(packageName, className);
+ composer.addImport("com.google.gwt.core.client.GWT");
+ composer
+ .setSuperclass("com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterionFactory");
+ SourceWriter sourceWriter = composer.createSourceWriter(context,
+ printWriter);
+
+ // generator constructor source code
+ generateInstantiatorMethod(sourceWriter, context, logger);
+ // close generated class
+ sourceWriter.outdent();
+ sourceWriter.println("}");
+ // commit generated class
+ context.commit(logger, printWriter);
+ logger.log(Type.INFO, "Done. ("
+ + (new Date().getTime() - date.getTime()) / 1000 + "seconds)");
+
+ }
+
+ private Collection<JClassType> getAvailableCriteria(GeneratorContext context) {
+
+ Collection<JClassType> crits = new LinkedList<JClassType>();
+
+ JClassType[] types = context.getTypeOracle().getTypes();
+ for (int i = 0; i < types.length; i++) {
+ JClassType jClassType = types[i];
+ JClassType[] implementedInterfaces = jClassType
+ .getImplementedInterfaces();
+ for (int j = 0; j < implementedInterfaces.length; j++) {
+ String qualifiedSourceName = implementedInterfaces[j]
+ .getQualifiedSourceName();
+ if (qualifiedSourceName
+ .equals("com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriteria")) {
+ crits.add(jClassType);
+ }
+ }
+ }
+ return crits;
+ }
+
+ private void generateInstantiatorMethod(SourceWriter sourceWriter,
+ GeneratorContext context, TreeLogger logger) {
+
+ sourceWriter.println("public VAcceptCriteria get(String name) {");
+ sourceWriter.indent();
+
+ sourceWriter.println("name = name.intern();");
+
+ Collection<JClassType> paintablesHavingWidgetAnnotation = getAvailableCriteria(context);
+
+ for (JClassType jClassType : paintablesHavingWidgetAnnotation) {
+ ServerCriterion annotation = jClassType
+ .getAnnotation(ServerCriterion.class);
+ if (annotation == null) {
+ // throw new RuntimeException(
+ // "No server side implementation defined for "
+ // + jClassType.getName());
+ continue;
+ } else {
+ System.out.print("Printing for instantiation rule for "
+ + annotation.value());
+ }
+ String serversideclass = annotation.value();
+
+ sourceWriter.print("if (\"");
+ sourceWriter.print(serversideclass);
+ sourceWriter.print("\" == name) return GWT.create(");
+ sourceWriter.print(jClassType.getName());
+ sourceWriter.println(".class );");
+ sourceWriter.print("else ");
+
+ }
+ sourceWriter.println("return null;");
+ sourceWriter.outdent();
+ sourceWriter.println("}");
+ }
+
+}