Skip to content

Commit dfed8af

Browse files
author
Phillip Webb
committed
Only consider "is" methods with boolean returns
Fix regression introduced in b25e91a where ReflectivePropertyAccessor does not consider the return type for "is" getters. Issue: SPR-11142 (cherry picked from commit 85b0bff)
1 parent 236981a commit dfed8af

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

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

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
import java.lang.reflect.Method;
2323
import java.lang.reflect.Modifier;
2424
import java.util.Arrays;
25+
import java.util.Collections;
2526
import java.util.Comparator;
27+
import java.util.HashSet;
2628
import java.util.Map;
29+
import java.util.Set;
2730
import java.util.concurrent.ConcurrentHashMap;
2831

2932
import org.springframework.core.MethodParameter;
@@ -50,6 +53,17 @@
5053
*/
5154
public class ReflectivePropertyAccessor implements PropertyAccessor {
5255

56+
private static final Set<Class<?>> BOOLEAN_TYPES;
57+
static {
58+
Set<Class<?>> booleanTypes = new HashSet<Class<?>>();
59+
booleanTypes.add(Boolean.class);
60+
booleanTypes.add(Boolean.TYPE);
61+
BOOLEAN_TYPES = Collections.unmodifiableSet(booleanTypes);
62+
}
63+
64+
private static final Set<Class<?>> ANY_TYPES = Collections.emptySet();
65+
66+
5367
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
5468

5569
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
@@ -314,29 +328,33 @@ private Field findField(String name, Class<?> clazz, Object target) {
314328
* Find a getter method for the specified property.
315329
*/
316330
protected Method findGetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
317-
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
318-
new String[] { "get", "is" }, clazz, mustBeStatic, 0);
331+
Method method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
332+
"get", clazz, mustBeStatic, 0, ANY_TYPES);
333+
if (method == null) {
334+
method = findMethodForProperty(getPropertyMethodSuffixes(propertyName),
335+
"is", clazz, mustBeStatic, 0, BOOLEAN_TYPES);
336+
}
337+
return method;
319338
}
320339

321340
/**
322341
* Find a setter method for the specified property.
323342
*/
324343
protected Method findSetterForProperty(String propertyName, Class<?> clazz, boolean mustBeStatic) {
325344
return findMethodForProperty(getPropertyMethodSuffixes(propertyName),
326-
new String[] { "set" }, clazz, mustBeStatic, 1);
345+
"set", clazz, mustBeStatic, 1, ANY_TYPES);
327346
}
328347

329-
private Method findMethodForProperty(String[] methodSuffixes, String[] prefixes, Class<?> clazz,
330-
boolean mustBeStatic, int numberOfParams) {
348+
private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class<?> clazz,
349+
boolean mustBeStatic, int numberOfParams, Set<Class<?>> requiredReturnTypes) {
331350
Method[] methods = getSortedClassMethods(clazz);
332351
for (String methodSuffix : methodSuffixes) {
333-
for (String prefix : prefixes) {
334-
for (Method method : methods) {
335-
if (method.getName().equals(prefix + methodSuffix)
336-
&& method.getParameterTypes().length == numberOfParams
337-
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))) {
338-
return method;
339-
}
352+
for (Method method : methods) {
353+
if (method.getName().equals(prefix + methodSuffix)
354+
&& method.getParameterTypes().length == numberOfParams
355+
&& (!mustBeStatic || Modifier.isStatic(method.getModifiers()))
356+
&& (requiredReturnTypes.isEmpty() || requiredReturnTypes.contains(method.getReturnType()))) {
357+
return method;
340358
}
341359
}
342360
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,6 +1831,17 @@ public void SPR_10486() throws Exception {
18311831
equalTo((Object) "name"));
18321832
}
18331833

1834+
@Test
1835+
public void SPR_11142() throws Exception {
1836+
SpelExpressionParser parser = new SpelExpressionParser();
1837+
StandardEvaluationContext context = new StandardEvaluationContext();
1838+
SPR11142 rootObject = new SPR11142();
1839+
Expression expression = parser.parseExpression("something");
1840+
thrown.expect(SpelEvaluationException.class);
1841+
thrown.expectMessage("property 'something' cannot be found");
1842+
expression.getValue(context, rootObject);
1843+
}
1844+
18341845

18351846
private static enum ABC {A, B, C}
18361847

@@ -1914,4 +1925,12 @@ public void setName(String name) {
19141925
}
19151926

19161927
}
1928+
1929+
static class SPR11142 {
1930+
1931+
public String isSomething() {
1932+
return "";
1933+
}
1934+
1935+
}
19171936
}

0 commit comments

Comments
 (0)