Cherry picking r9536 releases/[rel_#] for issue 4781 git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.2@9537 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/model/OwnerFieldClass.java b/user/src/com/google/gwt/uibinder/rebind/model/OwnerFieldClass.java index 4cabead..dd09b6e 100644 --- a/user/src/com/google/gwt/uibinder/rebind/model/OwnerFieldClass.java +++ b/user/src/com/google/gwt/uibinder/rebind/model/OwnerFieldClass.java
@@ -28,6 +28,7 @@ import com.google.gwt.uibinder.rebind.MortalLogger; import com.google.gwt.uibinder.rebind.UiBinderContext; +import java.beans.Introspector; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -44,8 +45,8 @@ */ public class OwnerFieldClass { - private static final int defaultCost = 4; - private static final Map<String, Integer> typeRank; + private static final int DEFAULT_COST = 4; + private static final Map<String, Integer> TYPE_RANK; static { HashMap<String, Integer> tmpTypeRank = new HashMap<String, Integer>(); tmpTypeRank.put("java.lang.String", 1); @@ -65,7 +66,7 @@ tmpTypeRank.put("java.lang.Integer", 3); tmpTypeRank.put("java.lang.Long", 3); tmpTypeRank.put("java.lang.Short", 3); - typeRank = Collections.unmodifiableMap(tmpTypeRank); + TYPE_RANK = Collections.unmodifiableMap(tmpTypeRank); } /** @@ -158,6 +159,24 @@ } /** + * Adds a setter for a given property to the given map of setters. + * + * @param allSetters the map of setters (keyed by property name) + * @param propertyName the property name to use + * @param method the setter to use + */ + private void addSetter(Map<String, Collection<JMethod>> allSetters, + String propertyName, JMethod method) { + Collection<JMethod> propertyMethods = allSetters.get(propertyName); + if (propertyMethods == null) { + propertyMethods = new ArrayList<JMethod>(); + allSetters.put(propertyName, propertyMethods); + } + + propertyMethods.add(method); + } + + /** * Given a collection of setters for the same property, picks which one to * use. Not having a proper setter is not an error unless of course the user * tries to use it. @@ -230,16 +249,15 @@ String propertyName = method.getName().substring(3); // turn "PropertyName" into "propertyName" - propertyName = propertyName.substring(0, 1).toLowerCase() + String beanPropertyName = Introspector.decapitalize(propertyName); + addSetter(allSetters, beanPropertyName, method); + + // keep backwards compatibility (i.e. hTML instead of HTML for setHTML) + String legacyPropertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1); - - Collection<JMethod> propertyMethods = allSetters.get(propertyName); - if (propertyMethods == null) { - propertyMethods = new ArrayList<JMethod>(); - allSetters.put(propertyName, propertyMethods); + if (!legacyPropertyName.equals(beanPropertyName)) { + addSetter(allSetters, legacyPropertyName, method); } - - propertyMethods.add(method); } return allSetters; @@ -349,7 +367,7 @@ * types, it will not be considered ambiguous. * * The cost mapping is defined in - * {@link #typeRank typeRank } + * {@link #TYPE_RANK typeRank } * @param method. * @return the rank of the method. */ @@ -358,9 +376,9 @@ int rank = 0; for (int i = 0; i < Math.min(params.length, 10); i++) { JType paramType = params[i].getType(); - int cost = defaultCost; - if (typeRank.containsKey(paramType.getQualifiedSourceName())) { - cost = typeRank.get(paramType.getQualifiedSourceName()); + int cost = DEFAULT_COST; + if (TYPE_RANK.containsKey(paramType.getQualifiedSourceName())) { + cost = TYPE_RANK.get(paramType.getQualifiedSourceName()); } assert (cost >= 0 && cost <= 0x07); rank = rank | (cost << (3 * i));
diff --git a/user/test/com/google/gwt/uibinder/rebind/model/OwnerFieldClassTest.java b/user/test/com/google/gwt/uibinder/rebind/model/OwnerFieldClassTest.java index 9c84e79..c34fc7a 100644 --- a/user/test/com/google/gwt/uibinder/rebind/model/OwnerFieldClassTest.java +++ b/user/test/com/google/gwt/uibinder/rebind/model/OwnerFieldClassTest.java
@@ -29,7 +29,7 @@ import com.google.gwt.uibinder.rebind.MortalLogger; import com.google.gwt.uibinder.rebind.UiBinderContext; import com.google.gwt.user.client.ui.CheckBox; -import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.HTML; import junit.framework.TestCase; @@ -51,23 +51,35 @@ } public void testOwnerFieldClass() throws Exception { - // Get the JType for a Label - JClassType labelType = gwtTypeAdapter.adaptJavaClass(Label.class); + // Get the JType for an HTML + JClassType htmlType = gwtTypeAdapter.adaptJavaClass(HTML.class); // Now get its field class model - OwnerFieldClass fieldClass = OwnerFieldClass.getFieldClass(labelType, + OwnerFieldClass fieldClass = OwnerFieldClass.getFieldClass(htmlType, MortalLogger.NULL, uiBinderCtx); // Check the class model properties - assertEquals(labelType, fieldClass.getRawType()); + assertEquals(htmlType, fieldClass.getRawType()); assertNull(fieldClass.getUiConstructor()); - JMethod setter = fieldClass.getSetter("visible"); - assertMethod(setter, "setVisible", JPrimitiveType.BOOLEAN); + // simple property: visible="" maps to setVisible + JMethod visibleSetter = fieldClass.getSetter("visible"); + assertMethod(visibleSetter, "setVisible", JPrimitiveType.BOOLEAN); + + // all-upper-case property, Java Bean naming (all-upper-cased) + JMethod htmlSetter = fieldClass.getSetter("HTML"); + assertMethod(htmlSetter, "setHTML", + gwtTypeAdapter.adaptJavaClass(String.class)); + + // all-upper-case property, GWT-legacy naming with the first char + // lower-cased + htmlSetter = fieldClass.getSetter("hTML"); + assertMethod(htmlSetter, "setHTML", + gwtTypeAdapter.adaptJavaClass(String.class)); // Check that the same instance of the model is returned if asked again - assertSame(fieldClass, OwnerFieldClass.getFieldClass(labelType, - MortalLogger.NULL, uiBinderCtx)); + assertSame(fieldClass, + OwnerFieldClass.getFieldClass(htmlType, MortalLogger.NULL, uiBinderCtx)); gwtTypeAdapter.verifyAll(); } @@ -153,47 +165,47 @@ } // setvalue1 is not ambiguous - public void setValue1(boolean b) { + public void setValue1(@SuppressWarnings("unused") boolean b) { } - public void setValue1(Boolean b) { + public void setValue1(@SuppressWarnings("unused") Boolean b) { } // derived wins - public void setValue2(Integer b) { + public void setValue2(@SuppressWarnings("unused") Integer b) { } // this overload wins - public void setValue3(int b) { + public void setValue3(@SuppressWarnings("unused") int b) { } // this is not ambiguous since derived // has the exact same signature - public void setValue4(int b) { + public void setValue4(@SuppressWarnings("unused") int b) { } // setvalue5 is ambiguous - public void setValue5(float f) { + public void setValue5(@SuppressWarnings("unused") float f) { } - public void setValue5(double d) { + public void setValue5(@SuppressWarnings("unused") double d) { } // string always wins - public void setValue6(String s) { + public void setValue6(@SuppressWarnings("unused") String s) { } - public void setValue6(char s) { + public void setValue6(@SuppressWarnings("unused") char s) { } - public void setValue6(Object s) { + public void setValue6(@SuppressWarnings("unused") Object s) { } // primitive wins - public void setValue7(int s) { + public void setValue7(@SuppressWarnings("unused") int s) { } - public void setValue7(StringBuffer s) { + public void setValue7(@SuppressWarnings("unused") StringBuffer s) { } } @@ -207,10 +219,10 @@ super(); } - public void setValue2(int b) { + public void setValue2(@SuppressWarnings("unused") int b) { } - public void setValue3(Integer b) { + public void setValue3(@SuppressWarnings("unused") Integer b) { } public void setValue4(int b) { @@ -498,8 +510,7 @@ public void testOwnerFieldClass_withBadlyNamedMethod() { JClassType parentType = gwtTypeAdapter.adaptJavaClass(UiChildWithPoorMethodNames.class); try { - OwnerFieldClass parentClass = OwnerFieldClass.getFieldClass(parentType, - MortalLogger.NULL, uiBinderCtx); + OwnerFieldClass.getFieldClass(parentType, MortalLogger.NULL, uiBinderCtx); fail("Class should error because @UiChild method has invalid name (and no tag specified)."); } catch (UnableToCompleteException expected) { gwtTypeAdapter.verifyAll(); @@ -553,7 +564,7 @@ } } - public void testOwnerFieldClass_withMultipleUiConstructors() throws Exception { + public void testOwnerFieldClass_withMultipleUiConstructors() { JClassType constructorsType = gwtTypeAdapter.adaptJavaClass(MultiUiConstructorsClass.class); try {