revised wrapper type handling

This commit is contained in:
Juergen Hoeller 2009-08-09 06:36:16 +00:00
parent d41344eb1f
commit 2d7c2d6fff
12 changed files with 111 additions and 119 deletions

View File

@ -32,20 +32,22 @@ import org.springframework.util.ClassUtils;
* *
* @author Keith Donald * @author Keith Donald
* @author Andy Clement * @author Andy Clement
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
public class TypeDescriptor { public class TypeDescriptor {
public final static TypeDescriptor NULL = new TypeDescriptor((Class<?>) null); public final static TypeDescriptor NULL = new TypeDescriptor((Class<?>) null);
private Class<?> type;
private MethodParameter methodParameter; private MethodParameter methodParameter;
private Field field; private Field field;
private Annotation[] cachedFieldAnnotations; private Annotation[] cachedFieldAnnotations;
private Class<?> type;
/** /**
* Creates a new descriptor for the given type. * Creates a new descriptor for the given type.
@ -101,13 +103,13 @@ public class TypeDescriptor {
*/ */
public Class<?> getType() { public Class<?> getType() {
if (this.type != null) { if (this.type != null) {
return wrapperType(this.type); return this.type;
} }
else if (this.field != null) { else if (this.field != null) {
return wrapperType(this.field.getType()); return this.field.getType();
} }
else if (this.methodParameter != null) { else if (this.methodParameter != null) {
return wrapperType(this.methodParameter.getParameterType()); return this.methodParameter.getParameterType();
} }
else { else {
return null; return null;
@ -233,9 +235,9 @@ public class TypeDescriptor {
/** /**
* Is the obj an instance of this type? * Is the obj an instance of this type?
*/ */
public boolean isInstance(Object obj) { public boolean isAssignableValue(Object obj) {
Class<?> type = getType(); Class<?> type = getType();
return (type != null && getType().isInstance(obj)); return (type != null && ClassUtils.isAssignableValue(getType(), obj));
} }
/** /**
@ -283,32 +285,6 @@ public class TypeDescriptor {
// internal helpers // internal helpers
private Class<?> wrapperType(Class<?> type) {
if (type.isPrimitive()) {
if (type.equals(int.class)) {
return Integer.class;
} else if (type.equals(short.class)) {
return Short.class;
} else if (type.equals(long.class)) {
return Long.class;
} else if (type.equals(float.class)) {
return Float.class;
} else if (type.equals(double.class)) {
return Double.class;
} else if (type.equals(byte.class)) {
return Byte.class;
} else if (type.equals(boolean.class)) {
return Boolean.class;
} else if (type.equals(char.class)) {
return Character.class;
} else {
throw new IllegalStateException("Should never happen - primitive type is not a primitive?");
}
} else {
return type;
}
}
private Class<?> getArrayComponentType() { private Class<?> getArrayComponentType() {
return getType().getComponentType(); return getType().getComponentType();
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.core.convert.support; package org.springframework.core.convert.support;
import java.lang.reflect.Array; import java.lang.reflect.Array;
@ -23,7 +24,9 @@ import org.springframework.core.convert.TypeDescriptor;
* Special one-way converter that converts from a source array to a target array. Supports type conversion of the * Special one-way converter that converts from a source array to a target array. Supports type conversion of the
* individual array elements; for example, the ability to convert a String[] to an Integer[]. Mainly used internally by * individual array elements; for example, the ability to convert a String[] to an Integer[]. Mainly used internally by
* {@link org.springframework.core.convert.ConversionService} implementations. * {@link org.springframework.core.convert.ConversionService} implementations.
*
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -28,6 +28,7 @@ import org.springframework.core.convert.TypeDescriptor;
* specified. Supports type conversion of array elements when a parameterized target collection type descriptor is provided. * specified. Supports type conversion of array elements when a parameterized target collection type descriptor is provided.
* *
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
class ArrayToCollection extends AbstractCollectionConverter { class ArrayToCollection extends AbstractCollectionConverter {

View File

@ -24,7 +24,9 @@ import org.springframework.core.convert.TypeDescriptor;
/** /**
* Special converter that converts from target collection to a source array. * Special converter that converts from target collection to a source array.
*
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
class CollectionToArray extends AbstractCollectionConverter { class CollectionToArray extends AbstractCollectionConverter {
@ -49,16 +51,15 @@ class CollectionToArray extends AbstractCollectionConverter {
private ConversionExecutor getElementConverter(Collection<?> source) { private ConversionExecutor getElementConverter(Collection<?> source) {
ConversionExecutor elementConverter = getElementConverter(); ConversionExecutor elementConverter = getElementConverter();
if (elementConverter == NoOpConversionExecutor.INSTANCE) { if (elementConverter == NoOpConversionExecutor.INSTANCE) {
Iterator<?> it = source.iterator(); for (Object value : source) {
while (it.hasNext()) {
Object value = it.next();
if (value != null) { if (value != null) {
elementConverter = getConversionService().getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType())); elementConverter = getConversionService()
.getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
break; break;
} }
} }
} }
return elementConverter != null ? elementConverter : NoOpConversionExecutor.INSTANCE; return (elementConverter != null ? elementConverter : NoOpConversionExecutor.INSTANCE);
} }
} }

View File

@ -23,7 +23,9 @@ import org.springframework.core.convert.TypeDescriptor;
/** /**
* A converter that can convert from one collection type to another. * A converter that can convert from one collection type to another.
*
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -35,6 +35,7 @@ import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.ConverterInfo; import org.springframework.core.convert.converter.ConverterInfo;
import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/** /**
* Base implementation of a conversion service. * Base implementation of a conversion service.
@ -118,17 +119,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) { public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) {
ConversionExecutor executor = getConversionExecutor(sourceType, targetType); ConversionExecutor executor = getConversionExecutor(sourceType, targetType);
if (executor != null) { return (executor != null || (this.parent != null && this.parent.canConvert(sourceType, targetType)));
return true;
}
else {
if (parent != null) {
return parent.canConvert(sourceType, targetType);
}
else {
return false;
}
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -144,8 +135,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (executor != null) { if (executor != null) {
return executor.execute(source); return executor.execute(source);
} }
else { else if (this.parent != null) {
if (this.parent != null) {
return this.parent.convert(source, targetType); return this.parent.convert(source, targetType);
} }
else { else {
@ -154,7 +144,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
+ "] to targetType [" + targetType.getName() + "]"); + "] to targetType [" + targetType.getName() + "]");
} }
} }
}
ConversionExecutor getConversionExecutor(Class<?> sourceClass, TypeDescriptor targetType) ConversionExecutor getConversionExecutor(Class<?> sourceClass, TypeDescriptor targetType)
throws ConverterNotFoundException { throws ConverterNotFoundException {
@ -279,7 +268,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (sourceType.isAssignableTo(targetType)) { if (sourceType.isAssignableTo(targetType)) {
return NoOpConversionExecutor.INSTANCE; return NoOpConversionExecutor.INSTANCE;
} }
Converter converter = findRegisteredConverter(sourceType.getType(), targetType.getType()); Converter converter = findRegisteredConverter(ClassUtils.resolvePrimitiveIfNecessary(sourceType.getType()), ClassUtils.resolvePrimitiveIfNecessary(targetType.getType()));
if (converter != null) { if (converter != null) {
return new StaticConversionExecutor(sourceType, targetType, converter); return new StaticConversionExecutor(sourceType, targetType, converter);
} }
@ -361,7 +350,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
while (!classQueue.isEmpty()) { while (!classQueue.isEmpty()) {
Class currentClass = classQueue.removeLast(); Class currentClass = classQueue.removeLast();
Map<Class, Object> converters = getConvertersForSource(currentClass); Map<Class, Object> converters = getConvertersForSource(currentClass);
System.out.println("Source:" + currentClass);
Converter converter = getConverter(converters, targetType); Converter converter = getConverter(converters, targetType);
if (converter != null) { if (converter != null) {
return converter; return converter;

View File

@ -24,6 +24,7 @@ import org.springframework.core.convert.converter.Converter;
* Default conversion executor implementation for converters. * Default conversion executor implementation for converters.
* *
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
class StaticConversionExecutor implements ConversionExecutor { class StaticConversionExecutor implements ConversionExecutor {
@ -47,15 +48,15 @@ class StaticConversionExecutor implements ConversionExecutor {
if (source == null) { if (source == null) {
return null; return null;
} }
if (!this.sourceType.isInstance(source)) { if (!this.sourceType.isAssignableValue(source)) {
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), "Source object " throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(),
+ source + " to convert is expected to be an instance of [" + sourceType.getName() + "]"); "Source object " + source + " to convert is expected to be an instance of [" + this.sourceType.getName() + "]");
} }
try { try {
return this.converter.convert(source); return this.converter.convert(source);
} }
catch (Exception ex) { catch (Exception ex) {
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), ex); throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2009 the original author or authors. * Copyright 2002-2009 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.core.convert; package org.springframework.core.convert;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
@ -32,12 +33,6 @@ public class TypeDescriptorTests {
int[] intArray; int[] intArray;
List<String>[] arrayOfListOfString; List<String>[] arrayOfListOfString;
@Test
public void testWrapperType() {
TypeDescriptor desc = TypeDescriptor.valueOf(int.class);
assertEquals(Integer.class, desc.getType());
}
@Test @Test
public void listDescriptors() throws Exception { public void listDescriptors() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString")); TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString"));

View File

@ -136,7 +136,7 @@ public class GenericConversionServiceTests {
@Test @Test
public void convertArrayToPrimitiveArray() { public void convertArrayToPrimitiveArray() {
converter.add(new StringToInteger()); converter.add(new StringToInteger());
int[] result = (int[]) converter.convert(new String[] { "1", "2", "3" }, int[].class); int[] result = converter.convert(new String[] { "1", "2", "3" }, int[].class);
assertEquals(1, result[0]); assertEquals(1, result[0]);
assertEquals(2, result[1]); assertEquals(2, result[1]);
assertEquals(3, result[2]); assertEquals(3, result[2]);
@ -184,7 +184,7 @@ public class GenericConversionServiceTests {
list.add("1"); list.add("1");
list.add("2"); list.add("2");
list.add("3"); list.add("3");
String[] result = (String[]) converter.convert(list, String[].class); String[] result = converter.convert(list, String[].class);
assertEquals("1", result[0]); assertEquals("1", result[0]);
assertEquals("2", result[1]); assertEquals("2", result[1]);
assertEquals("3", result[2]); assertEquals("3", result[2]);
@ -229,14 +229,16 @@ public class GenericConversionServiceTests {
@Test @Test
public void convertStringToArrayWithElementConversion() { public void convertStringToArrayWithElementConversion() {
converter.add(new StringToInteger()); converter.add(new StringToInteger());
Integer[] result = (Integer[]) converter.convert("1,2,3", Integer[].class); Integer[] result = converter.convert("1,2,3", Integer[].class);
assertEquals(3, result.length); assertEquals(3, result.length);
assertEquals(new Integer(1), result[0]); assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]); assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]); assertEquals(new Integer(3), result[2]);
} }
public static enum FooEnum { public static enum FooEnum {
BAR, BAZ BAR, BAZ
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.expression; package org.springframework.expression;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
@ -27,11 +28,14 @@ import org.springframework.core.convert.TypeDescriptor;
*/ */
public class TypedValue { public class TypedValue {
private Object value;
private TypeDescriptor typeDescriptor;
public static final TypedValue NULL_TYPED_VALUE = new TypedValue(null, TypeDescriptor.NULL); public static final TypedValue NULL_TYPED_VALUE = new TypedValue(null, TypeDescriptor.NULL);
private final Object value;
private final TypeDescriptor typeDescriptor;
/** /**
* Create a TypedValue for a simple object. The type descriptor is inferred * Create a TypedValue for a simple object. The type descriptor is inferred
* from the object, so no generic information is preserved. * from the object, so no generic information is preserved.
@ -52,6 +56,7 @@ public class TypedValue {
this.typeDescriptor = typeDescriptor; this.typeDescriptor = typeDescriptor;
} }
public Object getValue() { public Object getValue() {
return this.value; return this.value;
} }
@ -60,10 +65,12 @@ public class TypedValue {
return this.typeDescriptor; return this.typeDescriptor;
} }
@Override @Override
public String toString() { public String toString() {
StringBuffer str = new StringBuffer(); StringBuilder str = new StringBuilder();
str.append("TypedValue: ").append(value).append(" of type "+typeDescriptor.asString()); str.append("TypedValue: ").append(this.value).append(" of type ").append(this.typeDescriptor.asString());
return str.toString(); return str.toString();
} }
} }

View File

@ -50,7 +50,8 @@ public class ReflectionHelper {
public static ArgumentsMatchInfo compareArguments( public static ArgumentsMatchInfo compareArguments(
Class[] expectedArgTypes, Class[] suppliedArgTypes, TypeConverter typeConverter) { Class[] expectedArgTypes, Class[] suppliedArgTypes, TypeConverter typeConverter) {
Assert.isTrue(expectedArgTypes.length==suppliedArgTypes.length, "Expected argument types and supplied argument types should be arrays of same length"); Assert.isTrue(expectedArgTypes.length == suppliedArgTypes.length,
"Expected argument types and supplied argument types should be arrays of same length");
ArgsMatchKind match = ArgsMatchKind.EXACT; ArgsMatchKind match = ArgsMatchKind.EXACT;
List<Integer> argsRequiringConversion = null; List<Integer> argsRequiringConversion = null;
@ -63,19 +64,21 @@ public class ReflectionHelper {
if (expectedArg.isPrimitive()) { if (expectedArg.isPrimitive()) {
match = null; match = null;
} }
} else { }
if (ClassUtils.isAssignable(expectedArg, suppliedArg) else {
/* || isWidenableTo(expectedArg, suppliedArg) */) { if (ClassUtils.isAssignable(expectedArg, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) { if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE; match = ArgsMatchKind.CLOSE;
} }
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) { }
else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) { if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>(); argsRequiringConversion = new ArrayList<Integer>();
} }
argsRequiringConversion.add(i); argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION; match = ArgsMatchKind.REQUIRES_CONVERSION;
} else { }
else {
match = null; match = null;
} }
} }
@ -83,14 +86,16 @@ public class ReflectionHelper {
} }
if (match == null) { if (match == null) {
return null; return null;
} else { }
else {
if (match == ArgsMatchKind.REQUIRES_CONVERSION) { if (match == ArgsMatchKind.REQUIRES_CONVERSION) {
int[] argsArray = new int[argsRequiringConversion.size()]; int[] argsArray = new int[argsRequiringConversion.size()];
for (int i = 0; i < argsRequiringConversion.size(); i++) { for (int i = 0; i < argsRequiringConversion.size(); i++) {
argsArray[i] = argsRequiringConversion.get(i); argsArray[i] = argsRequiringConversion.get(i);
} }
return new ArgumentsMatchInfo(match, argsArray); return new ArgumentsMatchInfo(match, argsArray);
} else { }
else {
return new ArgumentsMatchInfo(match); return new ArgumentsMatchInfo(match);
} }
} }
@ -125,19 +130,22 @@ public class ReflectionHelper {
if (expectedArg.isPrimitive()) { if (expectedArg.isPrimitive()) {
match=null; match=null;
} }
} else { }
else {
if (expectedArg != suppliedArg) { if (expectedArg != suppliedArg) {
if (expectedArg.isAssignableFrom(suppliedArg) || ClassUtils.isAssignableValue(expectedArg, suppliedArg)) { if (expectedArg.isAssignableFrom(suppliedArg) || ClassUtils.isAssignableValue(expectedArg, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) { if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE; match = ArgsMatchKind.CLOSE;
} }
} else if (typeConverter.canConvert(suppliedArg, expectedArg)) { }
else if (typeConverter.canConvert(suppliedArg, expectedArg)) {
if (argsRequiringConversion == null) { if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>(); argsRequiringConversion = new ArrayList<Integer>();
} }
argsRequiringConversion.add(i); argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION; match = ArgsMatchKind.REQUIRES_CONVERSION;
} else { }
else {
match = null; match = null;
} }
} }
@ -150,9 +158,10 @@ public class ReflectionHelper {
// Special case: there is one parameter left and it is an array and it matches the varargs expected argument - // 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 // that is a match, the caller has already built the array
if (suppliedArgTypes.length == expectedArgTypes.length if (suppliedArgTypes.length == expectedArgTypes.length &&
&& expectedArgTypes[expectedArgTypes.length - 1] == suppliedArgTypes[suppliedArgTypes.length - 1]) { 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();
@ -165,18 +174,21 @@ public class ReflectionHelper {
if (varargsParameterType.isPrimitive()) { if (varargsParameterType.isPrimitive()) {
match=null; match=null;
} }
} else { }
else {
if (ClassUtils.isAssignable(varargsParameterType, suppliedArg)) { if (ClassUtils.isAssignable(varargsParameterType, suppliedArg)) {
if (match != ArgsMatchKind.REQUIRES_CONVERSION) { if (match != ArgsMatchKind.REQUIRES_CONVERSION) {
match = ArgsMatchKind.CLOSE; match = ArgsMatchKind.CLOSE;
} }
} else if (typeConverter.canConvert(suppliedArg, varargsParameterType)) { }
else if (typeConverter.canConvert(suppliedArg, varargsParameterType)) {
if (argsRequiringConversion == null) { if (argsRequiringConversion == null) {
argsRequiringConversion = new ArrayList<Integer>(); argsRequiringConversion = new ArrayList<Integer>();
} }
argsRequiringConversion.add(i); argsRequiringConversion.add(i);
match = ArgsMatchKind.REQUIRES_CONVERSION; match = ArgsMatchKind.REQUIRES_CONVERSION;
} else { }
else {
match = null; match = null;
} }
} }
@ -186,7 +198,8 @@ public class ReflectionHelper {
if (match == null) { if (match == null) {
return null; return null;
} else { }
else {
if (match == ArgsMatchKind.REQUIRES_CONVERSION) { if (match == ArgsMatchKind.REQUIRES_CONVERSION) {
int[] argsArray = new int[argsRequiringConversion.size()]; int[] argsArray = new int[argsRequiringConversion.size()];
for (int i = 0; i < argsRequiringConversion.size(); i++) { for (int i = 0; i < argsRequiringConversion.size(); i++) {
@ -226,7 +239,8 @@ public class ReflectionHelper {
Class<?> targetType = null; Class<?> targetType = null;
if (isVarargs && argPosition >= (requiredParameterTypes.length - 1)) { if (isVarargs && argPosition >= (requiredParameterTypes.length - 1)) {
targetType = varargsType; targetType = varargsType;
} else { }
else {
targetType = requiredParameterTypes[argPosition]; targetType = requiredParameterTypes[argPosition];
} }
arguments[argPosition] = converter.convertValue(arguments[argPosition], TypeDescriptor.valueOf(targetType)); arguments[argPosition] = converter.convertValue(arguments[argPosition], TypeDescriptor.valueOf(targetType));
@ -260,7 +274,8 @@ public class ReflectionHelper {
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 {
@ -270,11 +285,13 @@ public class ReflectionHelper {
} }
arguments[i] = converter.convertValue(arguments[i], TypeDescriptor.valueOf(targetType)); arguments[i] = converter.convertValue(arguments[i], TypeDescriptor.valueOf(targetType));
} }
} catch (EvaluationException ex) { }
catch (EvaluationException ex) {
// allows for another type converter throwing a different kind of EvaluationException // allows for another type converter throwing a different kind of EvaluationException
if (ex instanceof SpelEvaluationException) { if (ex instanceof SpelEvaluationException) {
throw (SpelEvaluationException)ex; throw (SpelEvaluationException)ex;
} else { }
else {
throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,arguments[i].getClass().getName(),targetType); throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,arguments[i].getClass().getName(),targetType);
} }
} }
@ -338,13 +355,13 @@ public class ReflectionHelper {
*/ */
public static class ArgumentsMatchInfo { public static class ArgumentsMatchInfo {
public ArgsMatchKind kind; public final ArgsMatchKind kind;
public int[] argsRequiringConversion; public int[] argsRequiringConversion;
ArgumentsMatchInfo(ArgsMatchKind kind, int[] integers) { ArgumentsMatchInfo(ArgsMatchKind kind, int[] integers) {
this.kind = kind; this.kind = kind;
argsRequiringConversion = integers; this.argsRequiringConversion = integers;
} }
ArgumentsMatchInfo(ArgsMatchKind kind) { ArgumentsMatchInfo(ArgsMatchKind kind) {
@ -352,27 +369,27 @@ public class ReflectionHelper {
} }
public boolean isExactMatch() { public boolean isExactMatch() {
return kind==ArgsMatchKind.EXACT; return (this.kind == ArgsMatchKind.EXACT);
} }
public boolean isCloseMatch() { public boolean isCloseMatch() {
return kind==ArgsMatchKind.CLOSE; return (this.kind == ArgsMatchKind.CLOSE);
} }
public boolean isMatchRequiringConversion() { public boolean isMatchRequiringConversion() {
return kind==ArgsMatchKind.REQUIRES_CONVERSION; return (this.kind == ArgsMatchKind.REQUIRES_CONVERSION);
} }
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
sb.append("ArgumentMatch: ").append(kind); sb.append("ArgumentMatch: ").append(this.kind);
if (argsRequiringConversion!=null) { if (this.argsRequiringConversion != null) {
sb.append(" (argsForConversion:"); sb.append(" (argsForConversion:");
for (int i=0;i<argsRequiringConversion.length;i++) { for (int i = 0; i < this.argsRequiringConversion.length;i++) {
if (i > 0) { if (i > 0) {
sb.append(","); sb.append(",");
} }
sb.append(argsRequiringConversion[i]); sb.append(this.argsRequiringConversion[i]);
} }
sb.append(")"); sb.append(")");
} }

View File

@ -122,7 +122,6 @@ public class HelperTests extends ExpressionTestCase {
@Test @Test
public void testReflectionHelperCompareArguments_RequiresConversionMatching() { public void testReflectionHelperCompareArguments_RequiresConversionMatching() {
// TODO these are failing - for investigation
StandardTypeConverter typeConverter = new StandardTypeConverter(); StandardTypeConverter typeConverter = new StandardTypeConverter();
// Calling foo(String,int) with (String,Integer) requires boxing conversion of argument one // Calling foo(String,int) with (String,Integer) requires boxing conversion of argument one
@ -135,7 +134,7 @@ public class HelperTests extends ExpressionTestCase {
checkMatch(new Class[]{Integer.TYPE,Sub.class},new Class[]{Integer.class, Super.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0); checkMatch(new Class[]{Integer.TYPE,Sub.class},new Class[]{Integer.class, Super.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0);
// Passing (int,Sub,boolean) on call to foo(Integer,Super,Boolean) requires boxing conversion of arguments zero and two // Passing (int,Sub,boolean) on call to foo(Integer,Super,Boolean) requires boxing conversion of arguments zero and two
checkMatch(new Class[]{Integer.TYPE,Sub.class,Boolean.TYPE},new Class[]{Integer.class, Super.class,Boolean.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0,2); // TODO checkMatch(new Class[]{Integer.TYPE,Sub.class,Boolean.TYPE},new Class[]{Integer.class, Super.class,Boolean.class},typeConverter,ArgsMatchKind.REQUIRES_CONVERSION,0,2);
} }
@Test @Test