From d91a419fdc4f520ba8e443e689998f4e7b5a2b2c Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Mon, 31 Dec 2012 11:40:53 +0100 Subject: [PATCH] Fix SpEL JavaBean compliance for setters Prior to this change, SpEL was capable of handling getter methods for property names having a lowercase first letter and uppercase second letter such as: public String getiD() { ... } However, setters with the same naming arrangement were not supported, e.g.: public void setiD() { ... } This commit ensures that setters and getters are treated by SpEL equally in this regard, such that "iD"-style property names may be used anywhere within SpEL expressions. Issue: SPR-10122, SPR-9123 --- .../support/ReflectivePropertyAccessor.java | 24 +++++++++++-------- .../spel/support/ReflectionHelperTests.java | 15 +++++++++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 6e112b0e01..97d87d50c3 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -311,15 +311,10 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { */ 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); - } + String propertyMethodSuffix = getPropertyMethodSuffix(propertyName); + // Try "get*" method... - String getterName = "get" + propertyWriteMethodSuffix; + String getterName = "get" + propertyMethodSuffix; for (Method method : ms) { if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { @@ -327,7 +322,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { } } // Try "is*" method... - getterName = "is" + propertyWriteMethodSuffix; + getterName = "is" + propertyMethodSuffix; for (Method method : ms) { if (!method.isBridge() && method.getName().equals(getterName) && method.getParameterTypes().length == 0 && (boolean.class.equals(method.getReturnType()) || Boolean.class.equals(method.getReturnType())) && @@ -343,7 +338,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { */ protected Method findSetterForProperty(String propertyName, Class clazz, boolean mustBeStatic) { Method[] methods = clazz.getMethods(); - String setterName = "set" + StringUtils.capitalize(propertyName); + String setterName = "set" + getPropertyMethodSuffix(propertyName); for (Method method : methods) { if (!method.isBridge() && method.getName().equals(setterName) && method.getParameterTypes().length == 1 && (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) { @@ -353,6 +348,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { return null; } + protected String getPropertyMethodSuffix(String propertyName) { + if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) { + return propertyName; + } + else { + return StringUtils.capitalize(propertyName); + } + } + /** * Find a field of a certain name on a specified class */ diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java index 85764aa7a2..523fe69a68 100644 --- a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java +++ b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java @@ -22,7 +22,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import org.junit.Test; import org.springframework.core.convert.TypeDescriptor; @@ -329,6 +329,10 @@ public class ReflectionHelperTests extends ExpressionTestCase { // 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")); + + // SPR-10122, ReflectivePropertyAccessor JavaBean property names compliance tests - setters + rpr.write(ctx, t, "pEBS","Test String"); + Assert.assertEquals("Test String",rpr.read(ctx,t,"pEBS").getValue()); } @Test @@ -419,6 +423,7 @@ public class ReflectionHelperTests extends ExpressionTestCase { String iD = "iD"; String id = "id"; String ID = "ID"; + String pEBS = "pEBS"; public String getProperty() { return property; } public void setProperty(String value) { property = value; } @@ -434,6 +439,14 @@ public class ReflectionHelperTests extends ExpressionTestCase { public String getId() { return id; } public String getID() { return ID; } + + public String getpEBS() { + return pEBS; + } + + public void setpEBS(String pEBS) { + this.pEBS = pEBS; + } } static class Super {