Fixes UiBinder regression that broke custom subclasses of Image Review at http://gwt-code-reviews.appspot.com/302801 Review by: amitmanjhi@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7859 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java b/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java index ea3d122..8c122ea 100644 --- a/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java +++ b/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java
@@ -17,9 +17,11 @@ import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.JType; +import com.google.gwt.core.ext.typeinfo.TypeOracle; +import com.google.gwt.resources.client.ImageResource; import com.google.gwt.uibinder.rebind.UiBinderWriter; import com.google.gwt.uibinder.rebind.XMLElement; -import com.google.gwt.user.client.ui.Image; /** * Custom parsing of Image widgets. Sets ImageResource via constructor, because @@ -29,11 +31,17 @@ public void parse(XMLElement elem, String fieldName, JClassType type, UiBinderWriter writer) throws UnableToCompleteException { - String resource = elem.consumeImageResourceAttribute("resource"); - if (null != resource) { - writer.setFieldInitializerAsConstructor(fieldName, - writer.getOracle().findType(Image.class.getName()), - resource); + if (hasImageResourceConstructor(writer.getOracle(), type)) { + String resource = elem.consumeImageResourceAttribute("resource"); + if (null != resource) { + writer.setFieldInitializerAsConstructor(fieldName, type, resource); + } } } + + private boolean hasImageResourceConstructor(TypeOracle typeOracle, + JClassType type) { + JType imageResourceType = typeOracle.findType(ImageResource.class.getName()); + return type.findConstructor(new JType[] {imageResourceType}) != null; + } }
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/ImageParserTest.java b/user/test/com/google/gwt/uibinder/elementparsers/ImageParserTest.java index d2793ea..16a8705 100644 --- a/user/test/com/google/gwt/uibinder/elementparsers/ImageParserTest.java +++ b/user/test/com/google/gwt/uibinder/elementparsers/ImageParserTest.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; @@ -30,6 +31,32 @@ public class ImageParserTest extends TestCase { private static final String PARSED_TYPE = "com.google.gwt.user.client.ui.Image"; + private static final MockJavaResource IMAGE_SUBCLASS_NO_CONSTRUCTOR = new MockJavaResource( + "my.MyImage") { + @Override + protected CharSequence getContent() { + StringBuffer code = new StringBuffer(); + code.append("package my;\n"); + code.append("import com.google.gwt.user.client.ui.Image;\n"); + code.append("public class MyImage extends Image {\n"); + code.append("}\n"); + return code; + } + }; + private static final MockJavaResource IMAGE_SUBCLASS_RESOURCE_CONSTRUCTOR = new MockJavaResource( + "my.MyConstructedImage") { + @Override + protected CharSequence getContent() { + StringBuffer code = new StringBuffer(); + code.append("package my;\n"); + code.append("import com.google.gwt.user.client.ui.Image;\n"); + code.append("import com.google.gwt.resources.client.ImageResource;\n"); + code.append("public class MyConstructedImage extends Image {\n"); + code.append(" public MyConstructedImage(ImageResource r) { super(r); }"); + code.append("}\n"); + return code; + } + }; private ElementParserTester tester; @Override @@ -38,6 +65,52 @@ tester = new ElementParserTester(PARSED_TYPE, new ImageParser()); } + public void testHappyWithDefaultInstantiableSubclass() + throws UnableToCompleteException, SAXException, IOException { + tester = new ElementParserTester("my.MyImage", new ImageParser(), + IMAGE_SUBCLASS_NO_CONSTRUCTOR, IMAGE_SUBCLASS_RESOURCE_CONSTRUCTOR); + ImageParser parser = new ImageParser(); + 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:MyImage resource='{someImageResource}'/> "); + b.append("</ui:UiBinder>"); + + parser.parse(tester.getElem(b.toString(), "my:MyImage"), "fieldName", + tester.parsedType, tester.writer); + FieldWriter w = tester.fieldManager.lookup("fieldName"); + assertNull(w.getInitializer()); + + assertTrue(tester.writer.statements.isEmpty()); + assertNull(tester.logger.died); + } + + public void testHappyWithSubclassWithImageResourceConstructor() + throws UnableToCompleteException, SAXException, IOException { + ImageParser parser = new ImageParser(); + tester = new ElementParserTester("my.MyConstructedImage", new ImageParser(), + IMAGE_SUBCLASS_NO_CONSTRUCTOR, IMAGE_SUBCLASS_RESOURCE_CONSTRUCTOR); + + 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:MyConstructedImage resource='{someImageResource}'/> "); + b.append("</ui:UiBinder>"); + + parser.parse(tester.getElem(b.toString(), "my:MyConstructedImage"), "fieldName", + tester.parsedType, tester.writer); + FieldWriter w = tester.fieldManager.lookup("fieldName"); + assertEquals("new my.MyConstructedImage(someImageResource)", + w.getInitializer()); + + assertTrue(tester.writer.statements.isEmpty()); + assertNull(tester.logger.died); + } + public void testHappyWithResource() throws UnableToCompleteException, SAXException, IOException { StringBuffer b = new StringBuffer();
diff --git a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java index 861a0a7..c9e5c0e 100644 --- a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java +++ b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
@@ -174,8 +174,10 @@ protected CharSequence getContent() { StringBuffer code = new StringBuffer(); code.append("package com.google.gwt.user.client.ui;\n"); + code.append("import com.google.gwt.resources.client.ImageResource;\n"); code.append("public class Image extends Widget {\n"); code.append(" public Image() {} "); + code.append(" public Image(ImageResource r) {} "); code.append("}\n"); return code; } @@ -222,7 +224,7 @@ } }; public static final MockJavaResource LIST_BOX = new MockJavaResource( - "com.google.gwt.user.client.ui.ListBox") { + "com.google.gwt.user.client.ui.ListBox") { @Override protected CharSequence getContent() { StringBuffer code = new StringBuffer();
diff --git a/user/test/com/google/gwt/uibinder/test/client/FooImage.java b/user/test/com/google/gwt/uibinder/test/client/FooImage.java new file mode 100644 index 0000000..cfddeea --- /dev/null +++ b/user/test/com/google/gwt/uibinder/test/client/FooImage.java
@@ -0,0 +1,27 @@ +/* + * Copyright 2010 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.Image; + +/** + * Tests that custom Image subclasses work + */ +public class FooImage extends Image { + public FooImage() { + super(); + } +}
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 1967fdf..d519e4b 100644 --- a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java +++ b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
@@ -445,6 +445,15 @@ assertEquals("funny characters \" ' ' & < > > { }", t); } + public void testCustomImageClass() { + ImageResource resource = widgetUi.prettyImage; + Image widget = widgetUi.fooImage; + assertEquals(resource.getWidth(), widget.getOffsetWidth()); + assertEquals(resource.getHeight(), widget.getOffsetHeight()); + assertEquals(resource.getTop(), widget.getOriginTop()); + assertEquals(resource.getLeft(), widget.getOriginLeft()); + } + public void testImageResourceInImageWidget() { ImageResource resource = widgetUi.prettyImage; Image widget = widgetUi.babyWidget;
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 a74ceac..6040b3a 100644 --- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java +++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
@@ -126,6 +126,7 @@ @UiField SpanElement totallyPrivateStyleSpan; @UiField ImageResource prettyImage; @UiField ImageResource prettyTilingImage; + @UiField FooImage fooImage; @UiField Image babyWidget; @UiField ParagraphElement simpleSpriteParagraph; @UiField DataResource heartCursorResource;
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 40e8dba..09fa323 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
@@ -198,6 +198,9 @@ <gwt:Image ui:field='babyWidget' resource='{prettyImage}' altText='expected alt text' styleName='expected style name' /> + <demo:FooImage ui:field='fooImage' resource='{prettyImage}' + altText='expected alt text' styleName='expected style name' + /> </div> <p ui:field='simpleSpriteParagraph'