corrected use of AccessException (no longer used in ReflectionUtils)
This commit is contained in:
parent
7fa4d9e928
commit
e443c836fe
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.ConstructorExecutor;
|
import org.springframework.expression.ConstructorExecutor;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
import org.springframework.expression.EvaluationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple CommandExecutor implementation that runs a constructor using reflective invocation.
|
* A simple CommandExecutor implementation that runs a constructor using reflective invocation.
|
||||||
|
|
@ -36,19 +37,24 @@ public class ReflectionConstructorExecutor implements ConstructorExecutor {
|
||||||
private final Integer[] argsRequiringConversion;
|
private final Integer[] argsRequiringConversion;
|
||||||
|
|
||||||
public ReflectionConstructorExecutor(Constructor<?> constructor, Integer[] argsRequiringConversion) {
|
public ReflectionConstructorExecutor(Constructor<?> constructor, Integer[] argsRequiringConversion) {
|
||||||
this.c = constructor;
|
c = constructor;
|
||||||
this.argsRequiringConversion = argsRequiringConversion;
|
this.argsRequiringConversion = argsRequiringConversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke a constructor via reflection.
|
* Invoke a constructor via reflection.
|
||||||
*/
|
*/
|
||||||
public Object execute(EvaluationContext context, Object... arguments) throws AccessException {
|
public Object execute(EvaluationContext context, Object... arguments) throws AccessException {
|
||||||
if (argsRequiringConversion != null && arguments != null) {
|
if (argsRequiringConversion != null && arguments != null) {
|
||||||
ReflectionUtils.convertArguments(c.getParameterTypes(), c.isVarArgs(), context.getTypeUtils().getTypeConverter(), argsRequiringConversion, arguments);
|
try {
|
||||||
|
ReflectionUtils.convertArguments(c.getParameterTypes(), c.isVarArgs(), context.getTypeUtils()
|
||||||
|
.getTypeConverter(), argsRequiringConversion, arguments);
|
||||||
|
} catch (EvaluationException ex) {
|
||||||
|
throw new AccessException("Problem invoking constructor on '" + c + "': " + ex.getMessage(), ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (c.isVarArgs()) {
|
if (c.isVarArgs()) {
|
||||||
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(c.getParameterTypes(),arguments);
|
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(c.getParameterTypes(), arguments);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!c.isAccessible()) {
|
if (!c.isAccessible()) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
import org.springframework.expression.EvaluationException;
|
||||||
import org.springframework.expression.MethodExecutor;
|
import org.springframework.expression.MethodExecutor;
|
||||||
|
|
||||||
public class ReflectionMethodExecutor implements MethodExecutor {
|
public class ReflectionMethodExecutor implements MethodExecutor {
|
||||||
|
|
@ -31,17 +32,22 @@ public class ReflectionMethodExecutor implements MethodExecutor {
|
||||||
private final Integer[] argsRequiringConversion;
|
private final Integer[] argsRequiringConversion;
|
||||||
|
|
||||||
public ReflectionMethodExecutor(Method theMethod, Integer[] argumentsRequiringConversion) {
|
public ReflectionMethodExecutor(Method theMethod, Integer[] argumentsRequiringConversion) {
|
||||||
this.m = theMethod;
|
m = theMethod;
|
||||||
this.argsRequiringConversion = argumentsRequiringConversion;
|
argsRequiringConversion = argumentsRequiringConversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
|
public Object execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
|
||||||
if (argsRequiringConversion != null && arguments != null) {
|
if (argsRequiringConversion != null && arguments != null) {
|
||||||
ReflectionUtils.convertArguments(m.getParameterTypes(),m.isVarArgs(),context.getTypeUtils().getTypeConverter(), argsRequiringConversion, arguments);
|
try {
|
||||||
|
ReflectionUtils.convertArguments(m.getParameterTypes(), m.isVarArgs(), context.getTypeUtils()
|
||||||
|
.getTypeConverter(), argsRequiringConversion, arguments);
|
||||||
|
} catch (EvaluationException ex) {
|
||||||
|
throw new AccessException("Problem invoking method '" + m.getName() + "' on '" + target.getClass()
|
||||||
|
+ "': " + ex.getMessage(), ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m.isVarArgs()) {
|
if (m.isVarArgs()) {
|
||||||
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(m.getParameterTypes(),arguments);
|
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(m.getParameterTypes(), arguments);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!m.isAccessible()) {
|
if (!m.isAccessible()) {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.expression.AccessException;
|
|
||||||
import org.springframework.expression.EvaluationException;
|
import org.springframework.expression.EvaluationException;
|
||||||
import org.springframework.expression.TypeConverter;
|
import org.springframework.expression.TypeConverter;
|
||||||
import org.springframework.expression.spel.SpelException;
|
import org.springframework.expression.spel.SpelException;
|
||||||
|
|
@ -33,7 +32,6 @@ import org.springframework.expression.spel.SpelMessages;
|
||||||
* should be used in expressions.
|
* should be used in expressions.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ReflectionUtils {
|
public class ReflectionUtils {
|
||||||
|
|
@ -52,7 +50,7 @@ public class ReflectionUtils {
|
||||||
* @param type the type being searched for a valid constructor
|
* @param type the type being searched for a valid constructor
|
||||||
* @param argumentTypes the types of the arguments we want the constructor to have
|
* @param argumentTypes the types of the arguments we want the constructor to have
|
||||||
* @return a DiscoveredConstructor object or null if non found
|
* @return a DiscoveredConstructor object or null if non found
|
||||||
* @throws SpelException
|
* @throws SpelException
|
||||||
*/
|
*/
|
||||||
public static DiscoveredMethod findMethod(TypeConverter typeConverter, String name, Class<?>[] argumentTypes,
|
public static DiscoveredMethod findMethod(TypeConverter typeConverter, String name, Class<?>[] argumentTypes,
|
||||||
Class<?> type, boolean conversionAllowed) throws SpelException {
|
Class<?> type, boolean conversionAllowed) throws SpelException {
|
||||||
|
|
@ -68,12 +66,14 @@ public class ReflectionUtils {
|
||||||
}
|
}
|
||||||
if (method.getName().equals(name)) {
|
if (method.getName().equals(name)) {
|
||||||
ArgumentsMatchInfo matchInfo = null;
|
ArgumentsMatchInfo matchInfo = null;
|
||||||
if (method.isVarArgs() && argumentTypes.length>=(method.getParameterTypes().length-1)) {
|
if (method.isVarArgs() && argumentTypes.length >= (method.getParameterTypes().length - 1)) {
|
||||||
// *sigh* complicated
|
// *sigh* complicated
|
||||||
matchInfo = compareArgumentsVarargs(method.getParameterTypes(), argumentTypes, typeConverter, conversionAllowed);
|
matchInfo = compareArgumentsVarargs(method.getParameterTypes(), argumentTypes, typeConverter,
|
||||||
|
conversionAllowed);
|
||||||
} else if (method.getParameterTypes().length == argumentTypes.length) {
|
} else if (method.getParameterTypes().length == argumentTypes.length) {
|
||||||
// name and parameter number match, check the arguments
|
// name and parameter number match, check the arguments
|
||||||
matchInfo = compareArguments(method.getParameterTypes(), argumentTypes, typeConverter, conversionAllowed);
|
matchInfo = compareArguments(method.getParameterTypes(), argumentTypes, typeConverter,
|
||||||
|
conversionAllowed);
|
||||||
}
|
}
|
||||||
if (matchInfo != null) {
|
if (matchInfo != null) {
|
||||||
if (matchInfo.kind == ArgsMatchKind.EXACT) {
|
if (matchInfo.kind == ArgsMatchKind.EXACT) {
|
||||||
|
|
@ -81,7 +81,7 @@ public class ReflectionUtils {
|
||||||
} else if (matchInfo.kind == ArgsMatchKind.CLOSE) {
|
} else if (matchInfo.kind == ArgsMatchKind.CLOSE) {
|
||||||
closeMatch = method;
|
closeMatch = method;
|
||||||
} else if (matchInfo.kind == ArgsMatchKind.REQUIRES_CONVERSION) {
|
} else if (matchInfo.kind == ArgsMatchKind.REQUIRES_CONVERSION) {
|
||||||
if (matchRequiringConversion!=null) {
|
if (matchRequiringConversion != null) {
|
||||||
multipleOptions = true;
|
multipleOptions = true;
|
||||||
}
|
}
|
||||||
argsToConvert = matchInfo.argsRequiringConversion;
|
argsToConvert = matchInfo.argsRequiringConversion;
|
||||||
|
|
@ -94,7 +94,7 @@ public class ReflectionUtils {
|
||||||
return new DiscoveredMethod(closeMatch, null);
|
return new DiscoveredMethod(closeMatch, null);
|
||||||
} else if (matchRequiringConversion != null) {
|
} else if (matchRequiringConversion != null) {
|
||||||
if (multipleOptions) {
|
if (multipleOptions) {
|
||||||
throw new SpelException(SpelMessages.MULTIPLE_POSSIBLE_METHODS,name);
|
throw new SpelException(SpelMessages.MULTIPLE_POSSIBLE_METHODS, name);
|
||||||
}
|
}
|
||||||
return new DiscoveredMethod(matchRequiringConversion, argsToConvert);
|
return new DiscoveredMethod(matchRequiringConversion, argsToConvert);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -125,12 +125,15 @@ public class ReflectionUtils {
|
||||||
Constructor matchRequiringConversion = null;
|
Constructor matchRequiringConversion = null;
|
||||||
for (int i = 0; i < ctors.length; i++) {
|
for (int i = 0; i < ctors.length; i++) {
|
||||||
Constructor ctor = ctors[i];
|
Constructor ctor = ctors[i];
|
||||||
if (ctor.isVarArgs() && argumentTypes.length>=(ctor.getParameterTypes().length-1)) {
|
if (ctor.isVarArgs() && argumentTypes.length >= (ctor.getParameterTypes().length - 1)) {
|
||||||
// *sigh* complicated
|
// *sigh* complicated
|
||||||
// Basically.. we have to have all parameters match up until the varargs one, then the rest of what is being provided should be
|
// Basically.. we have to have all parameters match up until the varargs one, then the rest of what is
|
||||||
// the same type whilst the final argument to the method must be an array of that (oh, how easy...not) - or the final parameter
|
// being provided should be
|
||||||
|
// the same type whilst the final argument to the method must be an array of that (oh, how easy...not) -
|
||||||
|
// or the final parameter
|
||||||
// we are supplied does match exactly (it is an array already).
|
// we are supplied does match exactly (it is an array already).
|
||||||
ArgumentsMatchInfo matchInfo = compareArgumentsVarargs(ctor.getParameterTypes(), argumentTypes, typeConverter, conversionAllowed);
|
ArgumentsMatchInfo matchInfo = compareArgumentsVarargs(ctor.getParameterTypes(), argumentTypes,
|
||||||
|
typeConverter, conversionAllowed);
|
||||||
if (matchInfo != null) {
|
if (matchInfo != null) {
|
||||||
if (matchInfo.kind == ArgsMatchKind.EXACT) {
|
if (matchInfo.kind == ArgsMatchKind.EXACT) {
|
||||||
return new DiscoveredConstructor(ctor, null);
|
return new DiscoveredConstructor(ctor, null);
|
||||||
|
|
@ -141,7 +144,7 @@ public class ReflectionUtils {
|
||||||
matchRequiringConversion = ctor;
|
matchRequiringConversion = ctor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ctor.getParameterTypes().length == argumentTypes.length) {
|
} else if (ctor.getParameterTypes().length == argumentTypes.length) {
|
||||||
// worth a closer look
|
// worth a closer look
|
||||||
ArgumentsMatchInfo matchInfo = compareArguments(ctor.getParameterTypes(), argumentTypes, typeConverter,
|
ArgumentsMatchInfo matchInfo = compareArguments(ctor.getParameterTypes(), argumentTypes, typeConverter,
|
||||||
|
|
@ -214,11 +217,11 @@ public class ReflectionUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare argument arrays and return information about whether they match. A supplied type converter and
|
* Compare argument arrays and return information about whether they match. A supplied type converter and
|
||||||
* conversionAllowed flag allow for matches to take into account that a type may be transformed into a different
|
* conversionAllowed flag allow for matches to take into account that a type may be transformed into a different
|
||||||
* type by the converter. This variant of compareArguments allows for a varargs match.
|
* type by the converter. This variant of compareArguments allows for a varargs match.
|
||||||
*
|
*
|
||||||
* @param expectedArgTypes the array of types the method/constructor is expecting
|
* @param expectedArgTypes the array of types the method/constructor is expecting
|
||||||
* @param suppliedArgTypes the array of types that are being supplied at the point of invocation
|
* @param suppliedArgTypes the array of types that are being supplied at the point of invocation
|
||||||
|
|
@ -228,12 +231,13 @@ public class ReflectionUtils {
|
||||||
* @return a MatchInfo object indicating what kind of match it was or null if it was not a match
|
* @return a MatchInfo object indicating what kind of match it was or null if it was not a match
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static ArgumentsMatchInfo compareArgumentsVarargs(Class[] expectedArgTypes, Class[] suppliedArgTypes, TypeConverter typeConverter, boolean conversionAllowed) {
|
private static ArgumentsMatchInfo compareArgumentsVarargs(Class[] expectedArgTypes, Class[] suppliedArgTypes,
|
||||||
|
TypeConverter typeConverter, boolean conversionAllowed) {
|
||||||
ArgsMatchKind match = ArgsMatchKind.EXACT;
|
ArgsMatchKind match = ArgsMatchKind.EXACT;
|
||||||
List<Integer> argsRequiringConversion = null;
|
List<Integer> argsRequiringConversion = null;
|
||||||
|
|
||||||
// Check up until the varargs argument:
|
// Check up until the varargs argument:
|
||||||
|
|
||||||
// Deal with the arguments up to 'expected number' - 1
|
// Deal with the arguments up to 'expected number' - 1
|
||||||
for (int i = 0; i < expectedArgTypes.length - 1 && match != null; i++) {
|
for (int i = 0; i < expectedArgTypes.length - 1 && match != null; i++) {
|
||||||
Class suppliedArg = suppliedArgTypes[i];
|
Class suppliedArg = suppliedArgTypes[i];
|
||||||
|
|
@ -256,41 +260,44 @@ public class ReflectionUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Already does not match
|
// Already does not match
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case: there is one parameter left and it is an array and it matches the varargs expected argument - that is a match, the caller has already built the array
|
// Special case: there is one parameter left and it is an array and it matches the varargs expected argument -
|
||||||
if (suppliedArgTypes.length==expectedArgTypes.length && expectedArgTypes[expectedArgTypes.length-1]==suppliedArgTypes[suppliedArgTypes.length-1]) {
|
// that is a match, the caller has already built the array
|
||||||
|
if (suppliedArgTypes.length == expectedArgTypes.length
|
||||||
|
&& expectedArgTypes[expectedArgTypes.length - 1] == suppliedArgTypes[suppliedArgTypes.length - 1]) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Now... we have the final argument in the method we are checking as a match and we have 0 or more other
|
||||||
// Now... we have the final argument in the method we are checking as a match and we have 0 or more other arguments left to pass to it.
|
// arguments left to pass to it.
|
||||||
Class varargsParameterType = expectedArgTypes[expectedArgTypes.length-1].getComponentType();
|
Class varargsParameterType = expectedArgTypes[expectedArgTypes.length - 1].getComponentType();
|
||||||
|
|
||||||
// All remaining parameters must be of this type or convertable to this type
|
// All remaining parameters must be of this type or convertable to this type
|
||||||
for (int i=expectedArgTypes.length-1;i<suppliedArgTypes.length;i++) {
|
for (int i = expectedArgTypes.length - 1; i < suppliedArgTypes.length; i++) {
|
||||||
Class suppliedArg = suppliedArgTypes[i];
|
Class suppliedArg = suppliedArgTypes[i];
|
||||||
if (varargsParameterType != suppliedArg) {
|
if (varargsParameterType != suppliedArg) {
|
||||||
if (varargsParameterType.isAssignableFrom(suppliedArg) || areBoxingCompatible(varargsParameterType, suppliedArg)
|
if (varargsParameterType.isAssignableFrom(suppliedArg)
|
||||||
/* || isWidenableTo(expectedArg, suppliedArg) */) {
|
|| areBoxingCompatible(varargsParameterType, suppliedArg)
|
||||||
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
|
/* || isWidenableTo(expectedArg, suppliedArg) */) {
|
||||||
match = ArgsMatchKind.CLOSE;
|
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
|
||||||
|
match = ArgsMatchKind.CLOSE;
|
||||||
|
}
|
||||||
|
} else if (typeConverter.canConvert(suppliedArg, varargsParameterType)) {
|
||||||
|
if (argsRequiringConversion == null) {
|
||||||
|
argsRequiringConversion = new ArrayList<Integer>();
|
||||||
|
}
|
||||||
|
argsRequiringConversion.add(i);
|
||||||
|
match = ArgsMatchKind.REQUIRES_CONVERSION;
|
||||||
|
} else {
|
||||||
|
match = null;
|
||||||
}
|
}
|
||||||
} else if (typeConverter.canConvert(suppliedArg, varargsParameterType)) {
|
|
||||||
if (argsRequiringConversion == null) {
|
|
||||||
argsRequiringConversion = new ArrayList<Integer>();
|
|
||||||
}
|
|
||||||
argsRequiringConversion.add(i);
|
|
||||||
match = ArgsMatchKind.REQUIRES_CONVERSION;
|
|
||||||
} else {
|
|
||||||
match = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (match == null) {
|
if (match == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -302,7 +309,6 @@ public class ReflectionUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO optimize implementation of areBoxingCompatible
|
// TODO optimize implementation of areBoxingCompatible
|
||||||
private static boolean areBoxingCompatible(Class class1, Class class2) {
|
private static boolean areBoxingCompatible(Class class1, Class class2) {
|
||||||
if (class1 == Integer.class && class2 == Integer.TYPE)
|
if (class1 == Integer.class && class2 == Integer.TYPE)
|
||||||
|
|
@ -402,7 +408,7 @@ public class ReflectionUtils {
|
||||||
|
|
||||||
ArgumentsMatchInfo(ArgsMatchKind kind, Integer[] integers) {
|
ArgumentsMatchInfo(ArgsMatchKind kind, Integer[] integers) {
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.argsRequiringConversion = integers;
|
argsRequiringConversion = integers;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentsMatchInfo(ArgsMatchKind kind) {
|
ArgumentsMatchInfo(ArgsMatchKind kind) {
|
||||||
|
|
@ -424,7 +430,7 @@ public class ReflectionUtils {
|
||||||
|
|
||||||
public DiscoveredConstructor(Constructor theConstructor, Integer[] argsToConvert) {
|
public DiscoveredConstructor(Constructor theConstructor, Integer[] argsToConvert) {
|
||||||
this.theConstructor = theConstructor;
|
this.theConstructor = theConstructor;
|
||||||
this.argumentsRequiringConversion = argsToConvert;
|
argumentsRequiringConversion = argsToConvert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,59 +444,62 @@ public class ReflectionUtils {
|
||||||
|
|
||||||
public DiscoveredMethod(Method theMethod, Integer[] argsToConvert) {
|
public DiscoveredMethod(Method theMethod, Integer[] argsToConvert) {
|
||||||
this.theMethod = theMethod;
|
this.theMethod = theMethod;
|
||||||
this.argumentsRequiringConversion = argsToConvert;
|
argumentsRequiringConversion = argsToConvert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convertArguments(Class[] parameterTypes,boolean isVarargs, TypeConverter converter ,Integer[] argsRequiringConversion, Object... arguments) throws AccessException {
|
static void convertArguments(Class[] parameterTypes, boolean isVarargs, TypeConverter converter,
|
||||||
|
Integer[] argsRequiringConversion, Object... arguments) throws EvaluationException {
|
||||||
Class varargsType = null;
|
Class varargsType = null;
|
||||||
if (isVarargs) {
|
if (isVarargs) {
|
||||||
varargsType = parameterTypes[parameterTypes.length-1].getComponentType();
|
varargsType = parameterTypes[parameterTypes.length - 1].getComponentType();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < argsRequiringConversion.length; i++) {
|
for (int i = 0; i < argsRequiringConversion.length; i++) {
|
||||||
int argPosition = argsRequiringConversion[i];
|
int argPosition = argsRequiringConversion[i];
|
||||||
Class targetType = null;
|
Class targetType = null;
|
||||||
if (isVarargs && argPosition>=(parameterTypes.length-1)) {
|
if (isVarargs && argPosition >= (parameterTypes.length - 1)) {
|
||||||
targetType = varargsType;
|
targetType = varargsType;
|
||||||
} else {
|
} else {
|
||||||
targetType = parameterTypes[argPosition];
|
targetType = parameterTypes[argPosition];
|
||||||
}
|
}
|
||||||
try {
|
// try {
|
||||||
arguments[argPosition] = converter.convertValue(arguments[argPosition],targetType);
|
arguments[argPosition] = converter.convertValue(arguments[argPosition], targetType);
|
||||||
} catch (EvaluationException e) {
|
// } catch (EvaluationException e) {
|
||||||
throw new AccessException("Converter failed to convert '" + arguments[argPosition] + " to type '"
|
// throw new SpelException(e, SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, "Converter failed to convert '"
|
||||||
+ targetType + "'", e);
|
// + arguments[argPosition] + " to type '" + targetType + "'");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convertArguments(Class[] parameterTypes,boolean isVarargs, TypeConverter converter , Object... arguments) throws AccessException {
|
static void convertArguments(Class[] parameterTypes, boolean isVarargs, TypeConverter converter,
|
||||||
|
Object... arguments) throws EvaluationException {
|
||||||
Class varargsType = null;
|
Class varargsType = null;
|
||||||
if (isVarargs) {
|
if (isVarargs) {
|
||||||
varargsType = parameterTypes[parameterTypes.length-1].getComponentType();
|
varargsType = parameterTypes[parameterTypes.length - 1].getComponentType();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < arguments.length; i++) {
|
for (int i = 0; i < arguments.length; i++) {
|
||||||
Class targetType = null;
|
Class targetType = null;
|
||||||
if (isVarargs && i>=(parameterTypes.length-1)) {
|
if (isVarargs && i >= (parameterTypes.length - 1)) {
|
||||||
targetType = varargsType;
|
targetType = varargsType;
|
||||||
} else {
|
} else {
|
||||||
targetType = parameterTypes[i];
|
targetType = parameterTypes[i];
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (arguments[i]!=null && arguments[i].getClass()!=targetType) {
|
if (arguments[i] != null && arguments[i].getClass() != targetType) {
|
||||||
arguments[i] = converter.convertValue(arguments[i],targetType);
|
arguments[i] = converter.convertValue(arguments[i], targetType);
|
||||||
}
|
}
|
||||||
} catch (EvaluationException e) {
|
} catch (EvaluationException e) {
|
||||||
throw new AccessException("Converter failed to convert '" + arguments[i] + " to type '"
|
throw new SpelException(e, SpelMessages.PROBLEM_DURING_TYPE_CONVERSION, "Converter failed to convert '"
|
||||||
+ targetType + "'", e);
|
+ arguments[i] + " to type '" + targetType + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package up the arguments so that they correctly match what is expected in parameterTypes. For example, if parameterTypes is (int, String[])
|
* Package up the arguments so that they correctly match what is expected in parameterTypes. For example, if
|
||||||
* because the second parameter was declared String... then if arguments is [1,"a","b"] then it must be repackaged as [1,new String[]{"a","b"}]
|
* parameterTypes is (int, String[]) because the second parameter was declared String... then if arguments is
|
||||||
* in order to match the expected parameterTypes.
|
* [1,"a","b"] then it must be repackaged as [1,new String[]{"a","b"}] in order to match the expected
|
||||||
|
* parameterTypes.
|
||||||
*
|
*
|
||||||
* @param parameterTypes the types of the parameters for the invocation
|
* @param parameterTypes the types of the parameters for the invocation
|
||||||
* @param arguments the arguments to be setup ready for the invocation
|
* @param arguments the arguments to be setup ready for the invocation
|
||||||
|
|
@ -499,37 +508,41 @@ public class ReflectionUtils {
|
||||||
static Object[] setupArgumentsForVarargsInvocation(Class[] parameterTypes, Object... arguments) {
|
static Object[] setupArgumentsForVarargsInvocation(Class[] parameterTypes, Object... arguments) {
|
||||||
// Check if array already built for final argument
|
// Check if array already built for final argument
|
||||||
int nParams = parameterTypes.length;
|
int nParams = parameterTypes.length;
|
||||||
int nArgs = arguments.length;
|
int nArgs = arguments.length;
|
||||||
|
|
||||||
// Check if repackaging is needed:
|
// Check if repackaging is needed:
|
||||||
if (nParams!=arguments.length || parameterTypes[nParams-1]!=(arguments[nArgs-1]==null?null:arguments[nArgs-1].getClass())) {
|
if (nParams != arguments.length
|
||||||
|
|| parameterTypes[nParams - 1] != (arguments[nArgs - 1] == null ? null : arguments[nArgs - 1]
|
||||||
|
.getClass())) {
|
||||||
int arraySize = 0; // zero size array if nothing to pass as the varargs parameter
|
int arraySize = 0; // zero size array if nothing to pass as the varargs parameter
|
||||||
if (arguments!=null && nArgs>=nParams) {
|
if (arguments != null && nArgs >= nParams) {
|
||||||
arraySize = nArgs-(nParams-1);
|
arraySize = nArgs - (nParams - 1);
|
||||||
}
|
}
|
||||||
Object[] repackagedArguments = (Object[])Array.newInstance(parameterTypes[nParams-1].getComponentType(),arraySize);
|
Object[] repackagedArguments = (Object[]) Array.newInstance(parameterTypes[nParams - 1].getComponentType(),
|
||||||
|
arraySize);
|
||||||
|
|
||||||
// Copy all but the varargs arguments
|
// Copy all but the varargs arguments
|
||||||
for (int i=0;i<arraySize;i++) {
|
for (int i = 0; i < arraySize; i++) {
|
||||||
repackagedArguments[i] = arguments[nParams+i-1];
|
repackagedArguments[i] = arguments[nParams + i - 1];
|
||||||
}
|
}
|
||||||
// Create an array for the varargs arguments
|
// Create an array for the varargs arguments
|
||||||
Object[] newArgs = new Object[nParams];
|
Object[] newArgs = new Object[nParams];
|
||||||
for (int i=0;i<newArgs.length - 1;i++) {
|
for (int i = 0; i < newArgs.length - 1; i++) {
|
||||||
newArgs[i] = arguments[i];
|
newArgs[i] = arguments[i];
|
||||||
}
|
}
|
||||||
newArgs[newArgs.length-1] = repackagedArguments;
|
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||||
return newArgs;
|
return newArgs;
|
||||||
}
|
}
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object[] prepareArguments(TypeConverter converter, Method m, Object[] arguments) throws AccessException {//TODO should not be accessexception
|
public static Object[] prepareArguments(TypeConverter converter, Method m, Object[] arguments)
|
||||||
|
throws EvaluationException {
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
ReflectionUtils.convertArguments(m.getParameterTypes(),m.isVarArgs(),converter, arguments);
|
ReflectionUtils.convertArguments(m.getParameterTypes(), m.isVarArgs(), converter, arguments);
|
||||||
}
|
}
|
||||||
if (m.isVarArgs()) {
|
if (m.isVarArgs()) {
|
||||||
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(m.getParameterTypes(),arguments);
|
arguments = ReflectionUtils.setupArgumentsForVarargsInvocation(m.getParameterTypes(), arguments);
|
||||||
}
|
}
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue