Consistent resolution of Class methods and static methods

Issue: SPR-12502
This commit is contained in:
Juergen Hoeller 2014-12-03 23:03:24 +01:00
parent 1de71511f0
commit 9ef0bdcb17
2 changed files with 39 additions and 10 deletions

View File

@ -17,12 +17,13 @@
package org.springframework.expression.spel.support; package org.springframework.expression.spel.support;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -107,7 +108,7 @@ public class ReflectiveMethodResolver implements MethodResolver {
try { try {
TypeConverter typeConverter = context.getTypeConverter(); TypeConverter typeConverter = context.getTypeConverter();
Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass()); Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
List<Method> methods = new ArrayList<Method>(Arrays.asList(getMethods(type, targetObject))); List<Method> methods = new ArrayList<Method>((getMethods(type, targetObject)));
// If a filter is registered for this type, call it // If a filter is registered for this type, call it
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); MethodFilter filter = (this.filters != null ? this.filters.get(type) : null);
@ -216,14 +217,22 @@ public class ReflectiveMethodResolver implements MethodResolver {
} }
} }
private Method[] getMethods(Class<?> type, Object targetObject) { private Collection<Method> getMethods(Class<?> type, Object targetObject) {
if (targetObject instanceof Class) { if (targetObject instanceof Class) {
Set<Method> methods = new HashSet<Method>(); Set<Method> result = new LinkedHashSet<Method>();
methods.addAll(Arrays.asList(getMethods(type))); result.addAll(Arrays.asList(getMethods(targetObject.getClass())));
methods.addAll(Arrays.asList(getMethods(targetObject.getClass()))); // Add these also so that static result are invocable on the type: e.g. Float.valueOf(..)
return methods.toArray(new Method[methods.size()]); Method[] methods = getMethods(type);
for (Method method : methods) {
if (Modifier.isStatic(method.getModifiers())) {
result.add(method);
}
}
return result;
}
else {
return Arrays.asList(getMethods(type));
} }
return getMethods(type);
} }
/** /**

View File

@ -1208,7 +1208,7 @@ public class SpelReproTests extends AbstractExpressionTests {
@Override @Override
public Class<?>[] getSpecificTargetClasses() { public Class<?>[] getSpecificTargetClasses() {
return new Class[] { ContextObject.class }; return new Class<?>[] {ContextObject.class};
} }
@Override @Override
@ -1278,7 +1278,7 @@ public class SpelReproTests extends AbstractExpressionTests {
protected Method[] getMethods(Class<?> type) { protected Method[] getMethods(Class<?> type) {
try { try {
return new Method[] { return new Method[] {
Integer.class.getDeclaredMethod("parseInt", new Class[] { String.class, Integer.TYPE }) }; Integer.class.getDeclaredMethod("parseInt", new Class<?>[] {String.class, Integer.TYPE})};
} }
catch (NoSuchMethodException ex) { catch (NoSuchMethodException ex) {
return new Method[0]; return new Method[0];
@ -1878,6 +1878,14 @@ public class SpelReproTests extends AbstractExpressionTests {
assertEquals("child1", exp.getValue(context)); assertEquals("child1", exp.getValue(context));
} }
@Test
public void SPR12502() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("#root.getClass().getName()");
assertEquals(UnnamedUser.class.getName(), expression.getValue(new UnnamedUser()));
assertEquals(NamedUser.class.getName(), expression.getValue(new NamedUser()));
}
private static enum ABC { A, B, C } private static enum ABC { A, B, C }
@ -2151,4 +2159,16 @@ public class SpelReproTests extends AbstractExpressionTests {
} }
} }
public static class UnnamedUser {
}
public static class NamedUser {
public String getName() {
return "foo";
}
}
} }