Fix SpEL JavaBean compliance
Before this fix ReflectivePropertyAccessor was not able to find write method for valid property name that has first character in lower case and second character in upper case. Write method lookup would always convert first character of property name to upper case which is not compliant with JavaBean specification. As consequence this caused an unwanted behavior in SpEL when obtaining values of expressions that reference such JavaBean properties. As of this change, write method lookup skips conversion of property name first character to upper case when property name is longer than one character and second character is in upper case. This also fixes mentioned bug in SpEL value resolution. Issue: SPR-9123
This commit is contained in:
parent
2503b7eb89
commit
1f28bdfbfa
|
|
@ -282,13 +282,19 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Find a getter method for the specified property. A getter is defined as a method whose name start with the prefix
|
||||
* 'get' and the rest of the name is the same as the property name (with the first character uppercased).
|
||||
* Find a getter method for the specified property.
|
||||
*/
|
||||
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
||||
Method[] ms = clazz.getMethods();
|
||||
String propertyWriteMethodSuffix;
|
||||
if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) {
|
||||
propertyWriteMethodSuffix = propertyName;
|
||||
}
|
||||
else {
|
||||
propertyWriteMethodSuffix = StringUtils.capitalize(propertyName);
|
||||
}
|
||||
// Try "get*" method...
|
||||
String getterName = "get" + StringUtils.capitalize(propertyName);
|
||||
String getterName = "get" + propertyWriteMethodSuffix;
|
||||
for (Method method : ms) {
|
||||
if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 &&
|
||||
(!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
|
||||
|
|
@ -296,7 +302,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
|||
}
|
||||
}
|
||||
// Try "is*" method...
|
||||
getterName = "is" + StringUtils.capitalize(propertyName);
|
||||
getterName = "is" + propertyWriteMethodSuffix;
|
||||
for (Method method : ms) {
|
||||
if (method.getName().equals(getterName) && method.getParameterTypes().length == 0 &&
|
||||
boolean.class.equals(method.getReturnType()) &&
|
||||
|
|
|
|||
|
|
@ -319,6 +319,16 @@ public class ReflectionHelperTests extends ExpressionTestCase {
|
|||
Assert.assertEquals(false,rpr.read(ctx,t,"property4").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"property4"));
|
||||
|
||||
// repro SPR-9123, ReflectivePropertyAccessor JavaBean property names compliance tests
|
||||
Assert.assertEquals("iD",rpr.read(ctx,t,"iD").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"iD"));
|
||||
Assert.assertEquals("id",rpr.read(ctx,t,"id").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"id"));
|
||||
Assert.assertEquals("ID",rpr.read(ctx,t,"ID").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"ID"));
|
||||
// note: "Id" is not a valid JavaBean name, nevertheless it is treated as "id"
|
||||
Assert.assertEquals("id",rpr.read(ctx,t,"Id").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"Id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -406,6 +416,9 @@ public class ReflectionHelperTests extends ExpressionTestCase {
|
|||
String property2;
|
||||
String property3 = "doodoo";
|
||||
boolean property4 = false;
|
||||
String iD = "iD";
|
||||
String id = "id";
|
||||
String ID = "ID";
|
||||
|
||||
public String getProperty() { return property; }
|
||||
public void setProperty(String value) { property = value; }
|
||||
|
|
@ -415,6 +428,12 @@ public class ReflectionHelperTests extends ExpressionTestCase {
|
|||
public String getProperty3() { return property3; }
|
||||
|
||||
public boolean isProperty4() { return property4; }
|
||||
|
||||
public String getiD() { return iD; }
|
||||
|
||||
public String getId() { return id; }
|
||||
|
||||
public String getID() { return ID; }
|
||||
}
|
||||
|
||||
static class Super {
|
||||
|
|
|
|||
Loading…
Reference in New Issue