Browse Source

Only consider "is" methods with boolean returns

Fix regression introduced in b25e91a5 where ReflectivePropertyAccessor
does not consider the return type for "is" getters.

Issue: SPR-11142
pull/424/head
Phillip Webb 11 years ago
parent
commit
85b0bfff58
  1. 42
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java
  2. 19
      spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

42
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java

@ -22,8 +22,11 @@ import java.lang.reflect.Member; @@ -22,8 +22,11 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.MethodParameter;
@ -50,6 +53,17 @@ import org.springframework.util.StringUtils; @@ -50,6 +53,17 @@ import org.springframework.util.StringUtils;
*/
public class ReflectivePropertyAccessor implements PropertyAccessor {
private static final Set<Class<?>> BOOLEAN_TYPES;
static {
Set<Class<?>> booleanTypes = new HashSet<Class<?>>();
booleanTypes.add(Boolean.class);
booleanTypes.add(Boolean.TYPE);
BOOLEAN_TYPES = Collections.unmodifiableSet(booleanTypes);
}
private static final Set<Class<?>> ANY_TYPES = Collections.emptySet();
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
@ -319,8 +333,13 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { @@ -319,8 +333,13 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
* Find a getter method for the specified property.
*/
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
new String[] { "get", "is" }, clazz, mustBeStatic, 0);
Method method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
"get", clazz, mustBeStatic, 0, ANY_TYPES);
if (method == null) {
method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
"is", clazz, mustBeStatic, 0, BOOLEAN_TYPES);
}
return method;
}
/**
@ -328,20 +347,19 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { @@ -328,20 +347,19 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
*/
protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
new String[] { "set" }, clazz, mustBeStatic, 1);
"set", clazz, mustBeStatic, 1, ANY_TYPES);
}
private Method findMethodForProperty(String[] methodSuffixes, String[] prefixes, Class<?> clazz,
boolean mustBeStatic, int numberOfParams) {
private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class<?> clazz,
boolean mustBeStatic, int numberOfParams, Set<Class<?>> requiredReturnTypes) {
Method[] methods = getSortedClassMethods(clazz);
for (String methodSuffix : methodSuffixes) {
for (String prefix : prefixes) {
for (Method method : methods) {
if (method.getName().equals(prefix + methodSuffix)
&& method.getParameterTypes().length == numberOfParams
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
return method;
}
for (Method method : methods) {
if (method.getName().equals(prefix + methodSuffix)
&& method.getParameterTypes().length == numberOfParams
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))
&& (requiredReturnTypes.isEmpty() || requiredReturnTypes.contains(method.getReturnType()))) {
return method;
}
}
}

19
spring-expression/src/test/java/org/springframework/expression/spel/SpelReproTests.java

@ -1852,6 +1852,17 @@ public class SpelReproTests extends ExpressionTestCase { @@ -1852,6 +1852,17 @@ public class SpelReproTests extends ExpressionTestCase {
assertTrue(classNameExpression.getValue(map,Boolean.class));
}
@Test
public void SPR_11142() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
SPR11142 rootObject = new SPR11142();
Expression expression = parser.parseExpression("something");
thrown.expect(SpelEvaluationException.class);
thrown.expectMessage("property 'something' cannot be found");
expression.getValue(context, rootObject);
}
private static enum ABC {A, B, C}
@ -1956,4 +1967,12 @@ public class SpelReproTests extends ExpressionTestCase { @@ -1956,4 +1967,12 @@ public class SpelReproTests extends ExpressionTestCase {
}
}
static class SPR11142 {
public String isSomething() {
return "";
}
}
}

Loading…
Cancel
Save