SPR-8174: varargs and primitive handling in SpEL
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4157 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
5b07305e7d
commit
3b666f9897
|
|
@ -316,18 +316,73 @@ public class ReflectionHelper {
|
|||
if (argumentCount >= parameterCount) {
|
||||
arraySize = argumentCount - (parameterCount - 1);
|
||||
}
|
||||
Object[] repackagedArguments = (Object[]) Array.newInstance(requiredParameterTypes[parameterCount - 1].getComponentType(),
|
||||
arraySize);
|
||||
// Copy all but the varargs arguments
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = args[parameterCount + i - 1];
|
||||
}
|
||||
|
||||
// Create an array for the varargs arguments
|
||||
Object[] newArgs = new Object[parameterCount];
|
||||
for (int i = 0; i < newArgs.length - 1; i++) {
|
||||
newArgs[i] = args[i];
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
// Now sort out the final argument, which is the varargs one. Before entering this
|
||||
// method the arguments should have been converted to the box form of the required type.
|
||||
Class<?> componentType = requiredParameterTypes[parameterCount-1].getComponentType();
|
||||
if (componentType.isPrimitive()) {
|
||||
if (componentType==Integer.TYPE) {
|
||||
int[] repackagedArguments = (int[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Integer)args[parameterCount + i - 1]).intValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Float.TYPE) {
|
||||
float[] repackagedArguments = (float[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Float)args[parameterCount + i - 1]).floatValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Double.TYPE) {
|
||||
double[] repackagedArguments = (double[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Double)args[parameterCount + i - 1]).doubleValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Short.TYPE) {
|
||||
short[] repackagedArguments = (short[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Short)args[parameterCount + i - 1]).shortValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Character.TYPE) {
|
||||
char[] repackagedArguments = (char[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Character)args[parameterCount + i - 1]).charValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Byte.TYPE) {
|
||||
byte[] repackagedArguments = (byte[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Byte)args[parameterCount + i - 1]).byteValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Boolean.TYPE) {
|
||||
boolean[] repackagedArguments = (boolean[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Boolean)args[parameterCount + i - 1]).booleanValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
} else if(componentType==Long.TYPE) {
|
||||
long[] repackagedArguments = (long[]) Array.newInstance(componentType, arraySize);
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = ((Long)args[parameterCount + i - 1]).longValue();
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
}
|
||||
} else {
|
||||
Object[] repackagedArguments = (Object[]) Array.newInstance(componentType, arraySize);
|
||||
// Copy all but the varargs arguments
|
||||
for (int i = 0; i < arraySize; i++) {
|
||||
repackagedArguments[i] = args[parameterCount + i - 1];
|
||||
}
|
||||
newArgs[newArgs.length - 1] = repackagedArguments;
|
||||
}
|
||||
return newArgs;
|
||||
}
|
||||
return args;
|
||||
|
|
|
|||
|
|
@ -36,11 +36,13 @@ import org.springframework.expression.EvaluationContext;
|
|||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.MethodExecutor;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.standard.SpelExpression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.ReflectiveMethodResolver;
|
||||
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
|
|
@ -811,5 +813,109 @@ public class SpringEL300Tests extends ExpressionTestCase {
|
|||
assertEquals("[D(aaa), D(bbb), D(ccc)]",value3.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void varargsAndPrimitives_SPR8174() throws Exception {
|
||||
EvaluationContext emptyEvalContext = new StandardEvaluationContext();
|
||||
List<TypeDescriptor> args = new ArrayList<TypeDescriptor>();
|
||||
|
||||
args.add(TypeDescriptor.forObject(34L));
|
||||
ReflectionUtil<Integer> ru = new ReflectionUtil<Integer>();
|
||||
MethodExecutor me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"methodToCall",args);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject(23));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, 45);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject(23f));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, 45f);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject(23d));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, 23d);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject((short)23));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, (short)23);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject(23L));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, 23L);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject((char)65));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, (char)65);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject((byte)23));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, (byte)23);
|
||||
|
||||
args.set(0,TypeDescriptor.forObject(true));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"foo",args);
|
||||
me.execute(emptyEvalContext, ru, true);
|
||||
|
||||
// trickier:
|
||||
args.set(0,TypeDescriptor.forObject(12));
|
||||
args.add(TypeDescriptor.forObject(23f));
|
||||
me = new ReflectiveMethodResolver().resolve(emptyEvalContext,ru,"bar",args);
|
||||
me.execute(emptyEvalContext, ru, 12,23f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class ReflectionUtil<T extends Number> {
|
||||
public Object methodToCall(T param) {
|
||||
System.out.println(param+" "+param.getClass());
|
||||
return "Object methodToCall(T param)";
|
||||
}
|
||||
|
||||
public void foo(int... array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(float...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(double...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(short...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(long...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(boolean...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(char...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
public void foo(byte...array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void bar(int... array) {
|
||||
if (array.length==0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue