Make UiBinder handle custom subclasses of DialogBox
Reviewed by bobv
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7234 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java b/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
index 707f673..10ed6d6 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
@@ -27,18 +27,15 @@
public class DialogBoxParser implements ElementParser {
public void parse(XMLElement elem, String fieldName, JClassType type,
UiBinderWriter writer) throws UnableToCompleteException {
-
- String autoHide = elem.consumeBooleanAttribute("autoHide", false);
- String modal = elem.consumeBooleanAttribute("modal", true);
-
+
String caption = null;
String body = null;
for (XMLElement child : elem.consumeChildElements()) {
if ("caption".equals(child.getLocalName())) {
if (caption != null) {
- writer.die("In %s, may have only one <%s:caption>",
- elem, elem.getPrefix());
+ writer.die("In %s, may have only one <%s:caption>", elem,
+ elem.getPrefix());
}
HtmlInterpreter interpreter = HtmlInterpreter.newInterpreterForUiObject(
@@ -53,12 +50,11 @@
writer.die("In %s, found non-widget %s", elem, child);
}
body = writer.parseElementToField(child);
- }
+ }
}
+
+ handleConstructorArgs(elem, fieldName, type, writer);
- writer.setFieldInitializerAsConstructor(fieldName,
- writer.getOracle().findType(DialogBox.class.getCanonicalName()),
- autoHide, modal);
if (caption != null) {
writer.addStatement("%s.setHTML(\"%s\");", fieldName, caption);
}
@@ -66,4 +62,22 @@
writer.addStatement("%s.setWidget(%s);", fieldName, body);
}
}
+
+ /**
+ * If this is DialogBox (not a subclass), parse constructor args
+ * and generate the constructor call. For subtypes do nothing.
+ */
+ private void handleConstructorArgs(XMLElement elem, String fieldName,
+ JClassType type, UiBinderWriter writer) throws UnableToCompleteException {
+ boolean custom = !type.equals(writer.getOracle().findType(
+ DialogBox.class.getCanonicalName()));
+ if (!custom) {
+ String autoHide = elem.consumeBooleanAttribute("autoHide", false);
+ String modal = elem.consumeBooleanAttribute("modal", true);
+
+ writer.setFieldInitializerAsConstructor(fieldName,
+ writer.getOracle().findType(DialogBox.class.getCanonicalName()),
+ autoHide, modal);
+ }
+ }
}
diff --git a/user/src/com/google/gwt/uibinder/rebind/FieldWriter.java b/user/src/com/google/gwt/uibinder/rebind/FieldWriter.java
index 605e1de..95e81aa 100644
--- a/user/src/com/google/gwt/uibinder/rebind/FieldWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/FieldWriter.java
@@ -42,6 +42,9 @@
// this will need to become a set
JClassType getAssignableType();
+ /**
+ * @return the custom initializer for this field, or null if it is not set
+ */
String getInitializer();
/**
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java b/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
index e617807..3f8bda0 100644
--- a/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
+++ b/user/test/com/google/gwt/uibinder/elementparsers/DialogBoxParserTest.java
@@ -16,6 +16,7 @@
package com.google.gwt.uibinder.elementparsers;
import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.uibinder.rebind.FieldWriter;
import junit.framework.TestCase;
@@ -32,6 +33,20 @@
private static final String PARSED_TYPE = "com.google.gwt.user.client.ui.DialogBox";
+ private static final MockJavaResource DIALOG_SUBCLASS = new MockJavaResource(
+ "my.MyDialogBox") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DialogBox;\n");
+ code.append("public class MyDialogBox extends DialogBox {\n");
+ code.append(" public MyDialogBox() { super(false, true); }");
+ code.append("}\n");
+ return code;
+ }
+ };
+
private ElementParserTester tester;
@Override
@@ -143,7 +158,7 @@
assertNotNull(tester.logger.died);
}
}
-
+
public void testBadElemContent() throws SAXException, IOException {
StringBuffer b = new StringBuffer();
@@ -158,7 +173,7 @@
assertNotNull(tester.logger.died);
}
}
-
+
public void testBadTextContent() throws SAXException, IOException {
StringBuffer b = new StringBuffer();
@@ -175,4 +190,40 @@
assertNotNull(tester.logger.died);
}
}
+
+ public void testSubclassOkay() throws UnableToCompleteException,
+ SAXException, IOException {
+ DialogBoxParser parser = new DialogBoxParser();
+ String typeName = "my.MyDialogBox";
+ tester = new ElementParserTester(typeName, parser,
+ DIALOG_SUBCLASS);
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyDialogBox>");
+ b.append(" <g:caption>Hello, I <b>caption</b>you.</g:caption>");
+ b.append(" <g:Label>And your little dog, too!</g:Label>");
+ b.append(" </my:MyDialogBox> ");
+ b.append("</ui:UiBinder>");
+
+ String[] expected = {
+ "fieldName.setHTML(\"Hello, I <b>caption</b>you.\");",
+ "fieldName.setWidget(<g:Label>);",};
+
+ parser.parse(tester.getElem(b.toString(), "my:MyDialogBox"), "fieldName",
+ tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+
+ assertNull(w.getInitializer());
+
+ Iterator<String> i = tester.writer.statements.iterator();
+ for (String e : expected) {
+ assertEquals(e, i.next());
+ }
+ assertFalse(i.hasNext());
+ assertNull(tester.logger.died);
+ }
}
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
index 3fc4c22..0f01550 100644
--- a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
+++ b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
@@ -25,7 +25,6 @@
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.uibinder.attributeparsers.AttributeParsers;
-import com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers;
import com.google.gwt.uibinder.rebind.FieldManager;
import com.google.gwt.uibinder.rebind.FieldWriter;
import com.google.gwt.uibinder.rebind.MockMortalLogger;
@@ -44,6 +43,7 @@
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.Set;
/**
@@ -89,18 +89,22 @@
final ElementParser parser;
@SuppressWarnings("deprecation")
- ElementParserTester(String parsedTypeName, ElementParser parser)
- throws UnableToCompleteException {
+ ElementParserTester(String parsedTypeName, ElementParser parser,
+ Resource... moreJava) throws UnableToCompleteException {
this.parser = parser;
String templatePath = "TemplatePath.ui.xml";
String implName = "ImplClass";
+ Set<Resource> uiResources = getUiResources();
+ uiResources.addAll(Arrays.asList(moreJava));
CompilationState state = CompilationStateBuilder.buildFrom(createLogger(),
- getUiResources());
+ uiResources);
types = state.getTypeOracle();
+ // Fully qualified to avoid deprecation warning on the import line
+ com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers bundleParsers = new com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers(
+ types, logger, null, templatePath, null);
elemProvider = new XMLElementProviderImpl(new AttributeParsers(types, null,
- logger), new BundleAttributeParsers(types, logger, null, templatePath,
- null), types, logger);
+ logger), bundleParsers, types, logger);
fieldManager = new FieldManager(types, logger);
JClassType baseType = types.findType("my.Ui.BaseClass");
@@ -113,6 +117,17 @@
parsedType = types.findType(parsedTypeName);
}
+ public XMLElement getElem(String string, String tag) throws SAXException,
+ IOException {
+ Document doc = docHelper.documentFor(string);
+ Element w3cElem = (Element) doc.getDocumentElement().getElementsByTagName(
+ tag).item(0);
+ Assert.assertNotNull(String.format(
+ "Expected to find <%s> element in test DOM", tag), w3cElem);
+ XMLElement elem = elemProvider.get(w3cElem);
+ return elem;
+ }
+
public FieldWriter parse(String xml) throws UnableToCompleteException,
SAXException, IOException {
@@ -122,19 +137,9 @@
b.append(xml);
b.append("</ui:UiBinder>");
- parser.parse(getElem(b.toString()), FIELD_NAME, parsedType, writer);
- return fieldManager.lookup(FIELD_NAME);
- }
-
- private XMLElement getElem(String string) throws SAXException, IOException {
- Document doc = docHelper.documentFor(string);
String tag = "g:" + parsedType.getName();
- Element w3cElem = (Element) doc.getDocumentElement().getElementsByTagName(
- tag).item(0);
- Assert.assertNotNull(String.format(
- "Expected to find <%s> element in test DOM", tag), w3cElem);
- XMLElement elem = elemProvider.get(w3cElem);
- return elem;
+ parser.parse(getElem(b.toString(), tag), FIELD_NAME, parsedType, writer);
+ return fieldManager.lookup(FIELD_NAME);
}
private Set<Resource> getUiResources() {
diff --git a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
index 9aa6810..905b914 100644
--- a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
+++ b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
@@ -79,6 +79,7 @@
StringBuffer code = new StringBuffer();
code.append("package com.google.gwt.user.client.ui;\n");
code.append("public class DialogBox extends Widget {\n");
+ code.append(" public DialogBox(boolean autoHide, boolean modal) {} ");
code.append("}\n");
return code;
}
diff --git a/user/test/com/google/gwt/uibinder/test/client/FooDialog.java b/user/test/com/google/gwt/uibinder/test/client/FooDialog.java
new file mode 100644
index 0000000..525e88f
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/test/client/FooDialog.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009 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.test.client;
+
+import com.google.gwt.user.client.ui.DialogBox;
+
+/**
+ * A custom subclass of DialogBox, to prove we can use them.
+ */
+public class FooDialog extends DialogBox {
+ FooDialog() {
+ super(false, false);
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
index 30fcbcd..791a9b4 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
@@ -182,6 +182,13 @@
public void testCustomButtonBody() {
assertEquals("Hi mom", widgetUi.toggle.getText());
}
+
+ public void testCustomDialogBox() {
+ assertEquals("Custom dialog am I", widgetUi.fooDialog.getText());
+ Widget body = widgetUi.fooDialog.iterator().next();
+ assertTrue(body instanceof Label);
+ assertEquals("body", ((Label)body).getText());
+ }
public void testDomAccessAndComputedAttributeOnPlaceholderedElement() {
WidgetBasedUiExternalResources resources = GWT.create(WidgetBasedUiExternalResources.class);
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
index d80036c..1aa457e 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
@@ -152,6 +152,7 @@
@UiField DivElement bundledDivLegacy;
@UiField ToggleButton toggle;
@UiField HTML styleLess;
+ @UiField FooDialog fooDialog;
public WidgetBasedUi() {
external.style().ensureInjected();
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
index bd4fe66..285e3bc 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
@@ -534,6 +534,11 @@
<gwt:ToggleButton ui:field='toggle'>Hi mom</gwt:ToggleButton>
+ <demo:FooDialog ui:field='fooDialog'>
+ <gwt:caption>Custom dialog am I</gwt:caption>
+ <gwt:Label>body</gwt:Label>
+ </demo:FooDialog>
+
<h2>How to use the debugId, addStyleNames, addDependentStyleNames attributes</h2>
<p>You can use the <strong>debugId</strong>, <strong>addStyleNames</strong>, and <strong>addDependentStyleNames</strong>
attributes on any widget that extends UIObject.