Delegate Html element type lookups to a pluggable factory. Review at http://gwt-code-reviews.appspot.com/1352802 Review by: rjrjr@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9713 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/UiBinder.gwt.xml b/user/src/com/google/gwt/uibinder/UiBinder.gwt.xml index 541306a..bdf0743 100644 --- a/user/src/com/google/gwt/uibinder/UiBinder.gwt.xml +++ b/user/src/com/google/gwt/uibinder/UiBinder.gwt.xml
@@ -18,7 +18,9 @@ <source path="client"/> <source path="resources"/> - + <!-- Pluggable factory for creating field types for HTML elements --> + <define-configuration-property name="uibinder.html.elementfactory" is-multi-valued="false"/> + <set-configuration-property name="uibinder.html.elementfactory" value="com.google.gwt.uibinder.rebind.GwtDomHtmlElementFactory"/> <generate-with class="com.google.gwt.uibinder.rebind.UiBinderGenerator"> <when-type-assignable class="com.google.gwt.uibinder.client.UiBinder"/> </generate-with>
diff --git a/user/src/com/google/gwt/uibinder/rebind/GwtDomHtmlElementFactory.java b/user/src/com/google/gwt/uibinder/rebind/GwtDomHtmlElementFactory.java new file mode 100644 index 0000000..a0a4395 --- /dev/null +++ b/user/src/com/google/gwt/uibinder/rebind/GwtDomHtmlElementFactory.java
@@ -0,0 +1,43 @@ +/* + * Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.uibinder.rebind; + +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.TypeOracle; +import com.google.gwt.dom.client.TagName; + +/** + * Looks up implementation of DOM elements via @TagName interface in GWT DOM + * package. + */ +public class GwtDomHtmlElementFactory implements HtmlElementFactory { + + public JClassType findElementTypeForTag(String htmlTag, TypeOracle oracle) { + JClassType elementClass = oracle.findType("com.google.gwt.dom.client.Element"); + JClassType[] types = elementClass.getSubtypes(); + for (JClassType type : types) { + TagName annotation = type.getAnnotation(TagName.class); + if (annotation != null) { + for (String annotationTag : annotation.value()) { + if (annotationTag.equals(htmlTag)) { + return type; + } + } + } + } + return elementClass; + } +}
diff --git a/user/src/com/google/gwt/uibinder/rebind/HtmlElementFactory.java b/user/src/com/google/gwt/uibinder/rebind/HtmlElementFactory.java new file mode 100644 index 0000000..84f05ae --- /dev/null +++ b/user/src/com/google/gwt/uibinder/rebind/HtmlElementFactory.java
@@ -0,0 +1,27 @@ +/* + * Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.uibinder.rebind; + +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.TypeOracle; + +/** + * Looks up html tag names and returns corresponding type used to represent + * its bindings. + */ +public interface HtmlElementFactory { + JClassType findElementTypeForTag(String htmlTag, TypeOracle oracle); +}
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java index 57710e2..0c6e7e7 100644 --- a/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java +++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java
@@ -15,8 +15,10 @@ */ package com.google.gwt.uibinder.rebind; +import com.google.gwt.core.ext.ConfigurationProperty; import com.google.gwt.core.ext.Generator; import com.google.gwt.core.ext.GeneratorContext; +import com.google.gwt.core.ext.PropertyOracle; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.typeinfo.JClassType; @@ -115,9 +117,21 @@ packageName); PrintWriter printWriter = writers.tryToMakePrintWriterFor(implName); + Class<?> elementFactoryClass; + HtmlElementFactory elementFactory = null; + try { + PropertyOracle propertyOracle = genCtx.getPropertyOracle(); + ConfigurationProperty factoryProperty = propertyOracle + .getConfigurationProperty("uibinder.html.elementfactory"); + elementFactoryClass = Class.forName(factoryProperty.getValues().get(0)); + elementFactory = (HtmlElementFactory) elementFactoryClass.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + if (printWriter != null) { generateOnce(interfaceType, implName, printWriter, logger, oracle, - resourceOracle, writers, designTime); + resourceOracle, writers, designTime, elementFactory); } return packageName + "." + implName; } @@ -125,7 +139,8 @@ private void generateOnce(JClassType interfaceType, String implName, PrintWriter binderPrintWriter, TreeLogger treeLogger, TypeOracle oracle, ResourceOracle resourceOracle, PrintWriterManager writerManager, - DesignTimeUtils designTime) throws UnableToCompleteException { + DesignTimeUtils designTime, + HtmlElementFactory elementFactory) throws UnableToCompleteException { MortalLogger logger = new MortalLogger(treeLogger); String templatePath = deduceTemplateFile(logger, interfaceType); @@ -134,7 +149,7 @@ UiBinderWriter uiBinderWriter = new UiBinderWriter(interfaceType, implName, templatePath, oracle, logger, new FieldManager(oracle, logger), - messages, designTime, uiBinderCtx); + messages, designTime, uiBinderCtx, elementFactory); Document doc = getW3cDoc(logger, designTime, resourceOracle, templatePath); designTime.rememberPathForElements(doc);
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java index e6be10a..e8844b8 100644 --- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java +++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -19,7 +19,6 @@ import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.core.ext.typeinfo.JPackage; import com.google.gwt.core.ext.typeinfo.TypeOracle; -import com.google.gwt.dom.client.TagName; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.uibinder.attributeparsers.AttributeParser; import com.google.gwt.uibinder.attributeparsers.AttributeParsers; @@ -181,6 +180,9 @@ * The type we have been asked to generated, e.g. MyUiBinder */ private final JClassType baseClass; + + private final HtmlElementFactory elementFactory; + /** * The name of the class we're creating, e.g. MyUiBinderImpl */ @@ -227,7 +229,8 @@ public UiBinderWriter(JClassType baseClass, String implClassName, String templatePath, TypeOracle oracle, MortalLogger logger, FieldManager fieldManager, MessagesWriter messagesWriter, - DesignTimeUtils designTime, UiBinderContext uiBinderCtx) + DesignTimeUtils designTime, UiBinderContext uiBinderCtx, + HtmlElementFactory elementFactory) throws UnableToCompleteException { this.baseClass = baseClass; this.implClassName = implClassName; @@ -238,6 +241,7 @@ this.messages = messagesWriter; this.designTime = designTime; this.uiBinderCtx = uiBinderCtx; + this.elementFactory = elementFactory; // Check for possible misuse 'GWT.create(UiBinder.class)' JClassType uibinderItself = oracle.findType(UiBinder.class.getCanonicalName()); @@ -494,7 +498,7 @@ String tagName = elem.getLocalName(); if (!isWidgetElement(elem)) { - return findGwtDomElementTypeForTag(tagName); + return findDomElementTypeForTag(tagName); } String ns = elem.getNamespaceUri(); @@ -760,24 +764,10 @@ } /** - * Given a DOM tag name, return the corresponding - * {@link com.google.gwt.dom.client.Element} subclass. + * Given a DOM tag name, return the corresponding JSO subclass. */ - private JClassType findGwtDomElementTypeForTag(String tag) { - JClassType elementClass = oracle.findType("com.google.gwt.dom.client.Element"); - JClassType[] types = elementClass.getSubtypes(); - for (JClassType type : types) { - TagName annotation = type.getAnnotation(TagName.class); - if (annotation != null) { - for (String annotationTag : annotation.value()) { - if (annotationTag.equals(tag)) { - return type; - } - } - } - } - - return elementClass; + private JClassType findDomElementTypeForTag(String tag) { + return elementFactory.findElementTypeForTag(tag, oracle); } /**
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java index 3d9f200..14dbbff 100644 --- a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java +++ b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
@@ -30,6 +30,8 @@ import com.google.gwt.uibinder.rebind.FieldManager; import com.google.gwt.uibinder.rebind.FieldWriter; import com.google.gwt.uibinder.rebind.MockMortalLogger; +import com.google.gwt.uibinder.rebind.HtmlElementFactory; +import com.google.gwt.uibinder.rebind.GwtDomHtmlElementFactory; import com.google.gwt.uibinder.rebind.W3cDomHelper; import com.google.gwt.uibinder.rebind.XMLElement; import com.google.gwt.uibinder.rebind.XMLElementProvider; @@ -113,8 +115,9 @@ MessagesWriter messages = new MessagesWriter(BINDER_URI, logger, templatePath, baseType.getPackage().getName(), implName); + HtmlElementFactory elementFactory = new GwtDomHtmlElementFactory(); writer = new MockUiBinderWriter(baseType, implName, templatePath, types, - logger, fieldManager, messages); + logger, fieldManager, messages, elementFactory); fieldManager.registerField(types.findType(parsedTypeName), FIELD_NAME); parsedType = types.findType(parsedTypeName); }
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/MockUiBinderWriter.java b/user/test/com/google/gwt/uibinder/elementparsers/MockUiBinderWriter.java index b08ab16..a2984bc 100644 --- a/user/test/com/google/gwt/uibinder/elementparsers/MockUiBinderWriter.java +++ b/user/test/com/google/gwt/uibinder/elementparsers/MockUiBinderWriter.java
@@ -21,6 +21,7 @@ import com.google.gwt.uibinder.rebind.DesignTimeUtilsStub; import com.google.gwt.uibinder.rebind.FieldManager; import com.google.gwt.uibinder.rebind.MortalLogger; +import com.google.gwt.uibinder.rebind.HtmlElementFactory; import com.google.gwt.uibinder.rebind.UiBinderContext; import com.google.gwt.uibinder.rebind.UiBinderWriter; import com.google.gwt.uibinder.rebind.XMLElement; @@ -34,10 +35,11 @@ public MockUiBinderWriter(JClassType baseClass, String implClassName, String templatePath, TypeOracle oracle, MortalLogger logger, - FieldManager fieldManager, MessagesWriter messagesWriter) - throws UnableToCompleteException { + FieldManager fieldManager, MessagesWriter messagesWriter, + HtmlElementFactory factory) throws UnableToCompleteException { super(baseClass, implClassName, templatePath, oracle, logger, fieldManager, - messagesWriter, DesignTimeUtilsStub.EMPTY, new UiBinderContext()); + messagesWriter, DesignTimeUtilsStub.EMPTY, new UiBinderContext(), + factory); } @Override @@ -50,4 +52,4 @@ throws UnableToCompleteException { return elem.consumeOpeningTag(); } -} \ No newline at end of file +}