SPR-5899: Invoking methods or constructors passing null (including varargs support)

This commit is contained in:
Andy Clement
2009-07-06 19:21:26 +00:00
parent c254f389c0
commit eb69e7574b
4 changed files with 201 additions and 39 deletions

View File

@@ -81,7 +81,7 @@ public class ConstructorReference extends SpelNodeImpl {
TypedValue childValue = children[i + 1].getValueInternal(state);
Object value = childValue.getValue();
arguments[i] = value;
argumentTypes[i] = (value==null?Object.class:value.getClass());
argumentTypes[i] = (value==null?null:value.getClass());
}
ConstructorExecutor executorToUse = this.cachedExecutor;

View File

@@ -92,7 +92,7 @@ public class MethodReference extends SpelNodeImpl {
private Class<?>[] getTypes(Object... arguments) {
Class<?>[] argumentTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
argumentTypes[i] = (arguments[i]==null?Object.class:arguments[i].getClass());
argumentTypes[i] = (arguments[i]==null?null:arguments[i].getClass());
}
return argumentTypes;
}

View File

@@ -57,19 +57,26 @@ public class ReflectionHelper {
Class suppliedArg = suppliedArgTypes[i];
Class expectedArg = expectedArgTypes[i];
if (expectedArg != suppliedArg) {
if (ClassUtils.isAssignable(expectedArg, suppliedArg)
/* || isWidenableTo(expectedArg, suppliedArg) */) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE;
}
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>();
// The user may supply null - and that will be ok unless a primitive is expected
if (suppliedArg==null) {
if (expectedArg.isPrimitive()) {
match=null;
}
argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION;
} else {
match = null;
if (ClassUtils.isAssignable(expectedArg, suppliedArg)
/* || isWidenableTo(expectedArg, suppliedArg) */) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE;
}
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>();
}
argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION;
} else {
match = null;
}
}
}
}
@@ -113,23 +120,29 @@ public class ReflectionHelper {
for (int i = 0; i < argCountUpToVarargs && match != null; i++) {
Class suppliedArg = suppliedArgTypes[i];
Class<?> expectedArg = expectedArgTypes[i];
if (expectedArg != suppliedArg) {
if (expectedArg.isAssignableFrom(suppliedArg) || ClassUtils.isAssignableValue(expectedArg, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE;
if (suppliedArg==null) {
if (expectedArg.isPrimitive()) {
match=null;
}
} else {
if (expectedArg != suppliedArg) {
if (expectedArg.isAssignableFrom(suppliedArg) || ClassUtils.isAssignableValue(expectedArg, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE;
}
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>();
}
argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION;
} else {
match = null;
}
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>();
}
argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION;
} else {
match = null;
}
}
}
// If already confirmed it cannot be a match, then returnW
// If already confirmed it cannot be a match, then return
if (match == null) {
return null;
}
@@ -147,19 +160,24 @@ public class ReflectionHelper {
for (int i = expectedArgTypes.length - 1; i < suppliedArgTypes.length; i++) {
Class suppliedArg = suppliedArgTypes[i];
if (varargsParameterType != suppliedArg) {
if (ClassUtils.isAssignable(varargsParameterType, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE;
if (suppliedArg==null) {
if (varargsParameterType.isPrimitive()) {
match=null;
}
} else if (typeConverter.canConvert(suppliedArg, varargsParameterType)) {
if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>();
} else {
if (ClassUtils.isAssignable(varargsParameterType, suppliedArg)) {
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;
}
argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION;
}
else {
match = null;
}
}
}
@@ -167,8 +185,7 @@ public class ReflectionHelper {
if (match == null) {
return null;
}
else {
} else {
if (match == ArgsMatchKind.REQUIRES_CONVERSION) {
int[] argsArray = new int[argsRequiringConversion.size()];
for (int i = 0; i < argsRequiringConversion.size(); i++) {