Only consider "is" methods with boolean returns
Fix regression introduced inb25e91a5where ReflectivePropertyAccessor does not consider the return type for "is" getters. Issue: SPR-11142 (cherry picked from commit85b0bfff)
This commit is contained in:
parent
236981aaa9
commit
dfed8afb26
|
|
@ -22,8 +22,11 @@ import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
|
|
@ -50,6 +53,17 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class ReflectivePropertyAccessor implements PropertyAccessor {
|
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, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
|
||||||
|
|
||||||
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
|
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
|
||||||
|
|
@ -314,8 +328,13 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
* Find a getter method for the specified property.
|
* Find a getter method for the specified property.
|
||||||
*/
|
*/
|
||||||
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
||||||
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
|
Method method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
|
||||||
new String[] { "get", "is" }, clazz, mustBeStatic, 0);
|
"get", clazz, mustBeStatic, 0, ANY_TYPES);
|
||||||
|
if (method == null) {
|
||||||
|
method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
|
||||||
|
"is", clazz, mustBeStatic, 0, BOOLEAN_TYPES);
|
||||||
|
}
|
||||||
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -323,20 +342,19 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
*/
|
*/
|
||||||
protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
|
||||||
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
|
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,
|
private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class<?> clazz,
|
||||||
boolean mustBeStatic, int numberOfParams) {
|
boolean mustBeStatic, int numberOfParams, Set<Class<?>> requiredReturnTypes) {
|
||||||
Method[] methods = getSortedClassMethods(clazz);
|
Method[] methods = getSortedClassMethods(clazz);
|
||||||
for (String methodSuffix : methodSuffixes) {
|
for (String methodSuffix : methodSuffixes) {
|
||||||
for (String prefix : prefixes) {
|
for (Method method : methods) {
|
||||||
for (Method method : methods) {
|
if (method.getName().equals(prefix + methodSuffix)
|
||||||
if (method.getName().equals(prefix + methodSuffix)
|
&& method.getParameterTypes().length == numberOfParams
|
||||||
&& method.getParameterTypes().length == numberOfParams
|
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))
|
||||||
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
|
&& (requiredReturnTypes.isEmpty() || requiredReturnTypes.contains(method.getReturnType()))) {
|
||||||
return method;
|
return method;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1831,6 +1831,17 @@ public class SpelReproTests extends ExpressionTestCase {
|
||||||
equalTo((Object) "name"));
|
equalTo((Object) "name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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}
|
private static enum ABC {A, B, C}
|
||||||
|
|
||||||
|
|
@ -1914,4 +1925,12 @@ public class SpelReproTests extends ExpressionTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class SPR11142 {
|
||||||
|
|
||||||
|
public String isSomething() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue