|
|
@ -18,6 +18,8 @@ package org.springframework.expression.spel.support; |
|
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import java.util.Comparator; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
@ -33,11 +35,13 @@ import org.springframework.expression.MethodResolver; |
|
|
|
import org.springframework.expression.TypeConverter; |
|
|
|
import org.springframework.expression.TypeConverter; |
|
|
|
import org.springframework.expression.spel.SpelEvaluationException; |
|
|
|
import org.springframework.expression.spel.SpelEvaluationException; |
|
|
|
import org.springframework.expression.spel.SpelMessage; |
|
|
|
import org.springframework.expression.spel.SpelMessage; |
|
|
|
|
|
|
|
import org.springframework.util.CollectionUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A method resolver that uses reflection to locate the method that should be invoked. |
|
|
|
* A method resolver that uses reflection to locate the method that should be invoked. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Andy Clement |
|
|
|
* @author Andy Clement |
|
|
|
|
|
|
|
* @author Juergen Hoeller |
|
|
|
* @since 3.0 |
|
|
|
* @since 3.0 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ReflectiveMethodResolver implements MethodResolver { |
|
|
|
public class ReflectiveMethodResolver implements MethodResolver { |
|
|
@ -58,31 +62,41 @@ public class ReflectiveMethodResolver implements MethodResolver { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, |
|
|
|
public MethodExecutor resolve(EvaluationContext context, Object targetObject, String name, |
|
|
|
List<TypeDescriptor> argumentTypes) throws AccessException { |
|
|
|
List<TypeDescriptor> argumentTypes) throws AccessException { |
|
|
|
|
|
|
|
|
|
|
|
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()); |
|
|
|
Method[] methods = type.getMethods(); |
|
|
|
Method[] methods = type.getMethods(); |
|
|
|
|
|
|
|
|
|
|
|
// If a filter is registered for this type, call it
|
|
|
|
// If a filter is registered for this type, call it
|
|
|
|
MethodFilter methodfilter = (filters==null?null:filters.get(type)); |
|
|
|
MethodFilter filter = (this.filters != null ? this.filters.get(type) : null); |
|
|
|
if (methodfilter!=null) { |
|
|
|
if (filter != null) { |
|
|
|
List<Method> methodsForFiltering = new ArrayList<Method>(); |
|
|
|
List<Method> methodsForFiltering = new ArrayList<Method>(); |
|
|
|
for (Method method: methods) { |
|
|
|
for (Method method: methods) { |
|
|
|
methodsForFiltering.add(method); |
|
|
|
methodsForFiltering.add(method); |
|
|
|
} |
|
|
|
} |
|
|
|
List<Method> methodsFiltered = methodfilter.filter(methodsForFiltering); |
|
|
|
List<Method> methodsFiltered = filter.filter(methodsForFiltering); |
|
|
|
if (methodsFiltered == null || methodsFiltered.size()==0) { |
|
|
|
if (CollectionUtils.isEmpty(methodsFiltered)) { |
|
|
|
methods = NO_METHODS; |
|
|
|
methods = NO_METHODS; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]); |
|
|
|
methods = methodsFiltered.toArray(new Method[methodsFiltered.size()]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Arrays.sort(methods, new Comparator<Method>() { |
|
|
|
|
|
|
|
public int compare(Method m1, Method m2) { |
|
|
|
|
|
|
|
int m1pl = m1.getParameterTypes().length; |
|
|
|
|
|
|
|
int m2pl = m2.getParameterTypes().length; |
|
|
|
|
|
|
|
return (new Integer(m1pl)).compareTo(m2pl); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
Method closeMatch = null; |
|
|
|
Method closeMatch = null; |
|
|
|
int[] argsToConvert = null; |
|
|
|
int[] argsToConvert = null; |
|
|
|
boolean multipleOptions = false; |
|
|
|
|
|
|
|
Method matchRequiringConversion = null; |
|
|
|
Method matchRequiringConversion = null; |
|
|
|
|
|
|
|
boolean multipleOptions = false; |
|
|
|
|
|
|
|
|
|
|
|
for (Method method : methods) { |
|
|
|
for (Method method : methods) { |
|
|
|
if (method.isBridge()) { |
|
|
|
if (method.isBridge()) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
@ -139,7 +153,7 @@ public class ReflectiveMethodResolver implements MethodResolver { |
|
|
|
|
|
|
|
|
|
|
|
public void registerMethodFilter(Class<?> type, MethodFilter filter) { |
|
|
|
public void registerMethodFilter(Class<?> type, MethodFilter filter) { |
|
|
|
if (this.filters == null) { |
|
|
|
if (this.filters == null) { |
|
|
|
this.filters = new HashMap<Class<?>,MethodFilter>(); |
|
|
|
this.filters = new HashMap<Class<?>, MethodFilter>(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (filter == null) { |
|
|
|
if (filter == null) { |
|
|
|
this.filters.remove(type); |
|
|
|
this.filters.remove(type); |
|
|
|