Consistent resolution of Class methods and static methods
Issue: SPR-12502
This commit is contained in:
parent
1de71511f0
commit
9ef0bdcb17
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue