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
+}