From: Matti Tahvonen Date: Fri, 12 Feb 2010 16:13:29 +0000 (+0000) Subject: improving accept criterion system. Lookup now built with generator. Needs name optimi... X-Git-Tag: 6.7.0.beta1~1988^2~18 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=269bd9adf61590cd4b76fb357491fc2974843fd1;p=vaadin-framework.git improving accept criterion system. Lookup now built with generator. Needs name optimization, possibly inverting annotation direction to be similar with widgets svn changeset:11304/svn branch:6.3_dd --- diff --git a/src/com/vaadin/event/dd/acceptCriteria/AcceptAll.java b/src/com/vaadin/event/dd/acceptCriteria/AcceptAll.java index 5efdd6b7bd..8a6129130c 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/AcceptAll.java +++ b/src/com/vaadin/event/dd/acceptCriteria/AcceptAll.java @@ -20,7 +20,7 @@ public final class AcceptAll implements AcceptCriterion { public void paint(PaintTarget target) throws PaintException { target.startTag("-ac"); - target.addAttribute("name", "acceptAll"); + target.addAttribute("name", getClass().getCanonicalName()); target.endTag("-ac"); } diff --git a/src/com/vaadin/event/dd/acceptCriteria/And.java b/src/com/vaadin/event/dd/acceptCriteria/And.java index 54e809b06f..9517688f35 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/And.java +++ b/src/com/vaadin/event/dd/acceptCriteria/And.java @@ -26,7 +26,7 @@ public class And implements AcceptCriterion { 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"); diff --git a/src/com/vaadin/event/dd/acceptCriteria/ComponentFilter.java b/src/com/vaadin/event/dd/acceptCriteria/ComponentFilter.java index 3bfa267c70..dbaaac6ac8 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/ComponentFilter.java +++ b/src/com/vaadin/event/dd/acceptCriteria/ComponentFilter.java @@ -22,7 +22,7 @@ public class ComponentFilter implements AcceptCriterion { 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"); } diff --git a/src/com/vaadin/event/dd/acceptCriteria/IsDataBinded.java b/src/com/vaadin/event/dd/acceptCriteria/IsDataBinded.java index f579ec97f0..bbda232786 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/IsDataBinded.java +++ b/src/com/vaadin/event/dd/acceptCriteria/IsDataBinded.java @@ -20,7 +20,7 @@ public final class IsDataBinded implements AcceptCriterion { public void paint(PaintTarget target) throws PaintException { target.startTag("-ac"); - target.addAttribute("name", "needsItemId"); + target.addAttribute("name", getClass().getCanonicalName()); target.endTag("-ac"); } diff --git a/src/com/vaadin/event/dd/acceptCriteria/OverTreeNode.java b/src/com/vaadin/event/dd/acceptCriteria/OverTreeNode.java index 70965c6452..1241bf6cb3 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/OverTreeNode.java +++ b/src/com/vaadin/event/dd/acceptCriteria/OverTreeNode.java @@ -17,7 +17,7 @@ public class OverTreeNode implements AcceptCriterion { public void paint(PaintTarget target) throws PaintException { target.startTag("-ac"); - target.addAttribute("name", "overTreeNode"); + target.addAttribute("name", getClass().getCanonicalName()); target.endTag("-ac"); } diff --git a/src/com/vaadin/event/dd/acceptCriteria/ServerSideCriterion.java b/src/com/vaadin/event/dd/acceptCriteria/ServerSideCriterion.java index f9dcd61483..36a25346ca 100644 --- a/src/com/vaadin/event/dd/acceptCriteria/ServerSideCriterion.java +++ b/src/com/vaadin/event/dd/acceptCriteria/ServerSideCriterion.java @@ -31,6 +31,6 @@ public abstract class ServerSideCriterion implements Serializable, } protected String getIdentifier() { - return "-ss"; + return ServerSideCriterion.class.getCanonicalName(); } } diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml index 42fbde2b57..51fa9382bc 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -33,6 +33,11 @@ + + + + + diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptAll.java b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptAll.java new file mode 100644 index 0000000000..8600fe9fd5 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/AcceptAll.java @@ -0,0 +1,18 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/And.java b/src/com/vaadin/terminal/gwt/client/ui/dd/And.java new file mode 100644 index 0000000000..6eea108a42 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/And.java @@ -0,0 +1,58 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/ComponentCriteria.java b/src/com/vaadin/terminal/gwt/client/ui/dd/ComponentCriteria.java new file mode 100644 index 0000000000..198e58018e --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/ComponentCriteria.java @@ -0,0 +1,30 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/HasItemId.java b/src/com/vaadin/terminal/gwt/client/ui/dd/HasItemId.java new file mode 100644 index 0000000000..8c2bbee46f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/HasItemId.java @@ -0,0 +1,20 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/LazyInitItemIdentifiers.java b/src/com/vaadin/terminal/gwt/client/ui/dd/LazyInitItemIdentifiers.java new file mode 100644 index 0000000000..b1fed80336 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/LazyInitItemIdentifiers.java @@ -0,0 +1,53 @@ +/** + * + */ +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 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[] 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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/OverTreeNode.java b/src/com/vaadin/terminal/gwt/client/ui/dd/OverTreeNode.java new file mode 100644 index 0000000000..4948a31436 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/OverTreeNode.java @@ -0,0 +1,24 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/ServerAccept.java b/src/com/vaadin/terminal/gwt/client/ui/dd/ServerAccept.java new file mode 100644 index 0000000000..4cacfc1f4f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/ServerAccept.java @@ -0,0 +1,26 @@ +/** + * + */ +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 diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/ServerCriterion.java b/src/com/vaadin/terminal/gwt/client/ui/dd/ServerCriterion.java new file mode 100644 index 0000000000..3aca021146 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/ServerCriterion.java @@ -0,0 +1,18 @@ +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(); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java index 5134661603..6f49cacdf3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterion.java @@ -6,11 +6,10 @@ import com.google.gwt.core.client.GWT; * 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) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionFactory.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionFactory.java new file mode 100644 index 0000000000..15248542cc --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionFactory.java @@ -0,0 +1,28 @@ +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; + // } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java deleted file mode 100644 index fa18cd4c2e..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VAcceptCriterionImpl.java +++ /dev/null @@ -1,236 +0,0 @@ -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 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[] 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 instances = new HashMap(); - - /** - * 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 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); - } - } -} diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriterionGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriterionGenerator.java new file mode 100644 index 0000000000..b0dca0da20 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/AcceptCriterionGenerator.java @@ -0,0 +1,150 @@ +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 getAvailableCriteria(GeneratorContext context) { + + Collection crits = new LinkedList(); + + 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 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("}"); + } + +}