diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java index 21998d93549a7424365bb1860f371991d39c833b..a377cb40c6bc58b62d1e90ca910391362b793185 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java @@ -32,39 +32,39 @@ public class ConversionExecutionException extends ConversionException { /** * The source type we tried to convert the value from. */ - private Class sourceClass; + private TypeDescriptor sourceType; /** * The target type we tried to convert the value to. */ - private Class targetClass; + private TypeDescriptor targetType; /** * Creates a new conversion exception. * @param value the value we tried to convert - * @param sourceClass the value's original type - * @param targetClass the value's target type + * @param sourceType the value's original type + * @param targetType the value's target type * @param cause the cause of the conversion failure */ - public ConversionExecutionException(Object value, Class sourceClass, Class targetClass, Throwable cause) { - super(defaultMessage(value, sourceClass, targetClass, cause), cause); + public ConversionExecutionException(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, Throwable cause) { + super(defaultMessage(value, sourceType, targetType, cause), cause); this.value = value; - this.sourceClass = sourceClass; - this.targetClass = targetClass; + this.sourceType = sourceType; + this.targetType = targetType; } /** * Creates a new conversion exception. * @param value the value we tried to convert - * @param sourceClass the value's original type - * @param targetClass the value's target type + * @param sourceType the value's original type + * @param targetType the value's target type * @param message a descriptive message of what went wrong. */ - public ConversionExecutionException(Object value, Class sourceClass, Class targetClass, String message) { + public ConversionExecutionException(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, String message) { super(message); this.value = value; - this.sourceClass = sourceClass; - this.targetClass = targetClass; + this.sourceType = sourceType; + this.targetType = targetType; } /** @@ -77,20 +77,20 @@ public class ConversionExecutionException extends ConversionException { /** * Returns the source type we tried to convert the value from. */ - public Class getSourceClass() { - return sourceClass; + public TypeDescriptor getSourceClass() { + return sourceType; } /** * Returns the target type we tried to convert the value to. */ - public Class getTargetClass() { - return targetClass; + public TypeDescriptor getTargetClass() { + return targetType; } - private static String defaultMessage(Object value, Class sourceClass, Class targetClass, Throwable cause) { - return "Unable to convert value " + StylerUtils.style(value) + " from type [" + sourceClass.getName() - + "] to type [" + targetClass.getName() + "]; reason = '" + cause.getMessage() + "'"; + private static String defaultMessage(Object value, TypeDescriptor sourceType, TypeDescriptor targetType, Throwable cause) { + return "Unable to convert value " + StylerUtils.style(value) + " from type [" + sourceType.getName() + + "] to type [" + targetType.getName() + "]; reason = '" + cause.getMessage() + "'"; } } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java index 56d7553e79f1882e443dfc40393cc56427916c81..ff7da4481ff400524690d18f8e1dad9f93427df3 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java @@ -22,23 +22,13 @@ package org.springframework.core.convert; * * @author Keith Donald */ -public interface ConversionExecutor { - - /** - * The type this executor converts from. - */ - public Class getSourceClass(); - - /** - * The type this executor converts to. -s */ - public Class getTargetClass(); +public interface ConversionExecutor { /** * Convert the source to T. * @param source the source to convert * @throws ConversionExecutionException if an exception occurs during type conversion */ - public T execute(S source) throws ConversionExecutionException; + public Object execute(Object source) throws ConversionExecutionException; } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutorNotFoundException.java b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutorNotFoundException.java index 82d485f3cf047165066d63572d3bd393f82d2826..6b743bc2dc64deee9d73ce4f7553c26892dd591b 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutorNotFoundException.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutorNotFoundException.java @@ -23,33 +23,33 @@ package org.springframework.core.convert; */ public class ConversionExecutorNotFoundException extends ConversionException { - private Class sourceClass; + private TypeDescriptor sourceType; - private Class targetClass; + private TypeDescriptor targetType; /** * Creates a new conversion executor not found exception. - * @param sourceClass the source type requested to convert from - * @param targetClass the target type requested to convert to + * @param sourceType the source type requested to convert from + * @param targetType the target type requested to convert to * @param message a descriptive message */ - public ConversionExecutorNotFoundException(Class sourceClass, Class targetClass, String message) { + public ConversionExecutorNotFoundException(TypeDescriptor sourceType, TypeDescriptor targetType, String message) { super(message); - this.sourceClass = sourceClass; - this.targetClass = targetClass; + this.sourceType = sourceType; + this.targetType = targetType; } /** * Returns the source type requested to convert from. */ - public Class getSourceClass() { - return sourceClass; + public TypeDescriptor getSourceType() { + return sourceType; } /** * Returns the target type requested to convert to. */ - public Class getTargetClass() { - return targetClass; + public TypeDescriptor getTargetType() { + return targetType; } } diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java index 1413acca4e25189db2667de96bb1c2bbaa9dd330..5f3edc83ccca556813f844cb9653b3e2a0df6455 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java @@ -26,61 +26,69 @@ package org.springframework.core.convert; public interface ConversionService { /** - * Convert the source to target class T. + * Returns true if the source can be converted to targetType. * @param source the source to convert from (may be null) - * @param targetClass the target class to convert to - * @return the converted object, an instance of the targetClass, or null if a null source + * @param targetType the target type to convert to + * @return true if a conversion can be performed, false if not + */ + public boolean canConvert(TypedValue source, TypeDescriptor targetType); + + /** + * Convert the source to target type T. + * @param source the source to convert from (may be null) + * @param targetType the target type to convert to + * @return the converted object, an instance of the targetType, or null if a null source * was provided * @throws ConversionExecutorNotFoundException if no suitable conversion executor could be found to convert the - * source to an instance of targetClass + * source to an instance of targetType * @throws ConversionException if an exception occurred during the conversion process */ - public T executeConversion(Object source, Class targetClass) throws ConversionExecutorNotFoundException, + public Object executeConversion(TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, ConversionException; /** - * Convert the source to target class T with a custom converter. + * Convert the source to target type T with a custom converter. * @param converterId the id of the custom converter, which must be registered with this conversion service and - * capable of converting to the targetClass + * capable of converting to the targetType * @param source the source to convert from (may be null) - * @param targetClass the target class to convert to - * @return the converted object, an instance of the targetClass, or null if a null source + * @param targetType the target type to convert to + * @return the converted object, an instance of the targetType, or null if a null source * was provided * @throws ConversionExecutorNotFoundException if no suitable conversion executor could be found to convert the - * source to an instance of targetClass + * source to an instance of targetType * @throws ConversionException if an exception occurred during the conversion process */ - public T executeConversion(String converterId, Object source, Class targetClass) + public Object executeConversion(String converterId, TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, ConversionException; /** * Get a ConversionExecutor that converts objects from S to T. * The returned ConversionExecutor is thread-safe and may safely be cached for later use by client code. - * @param sourceClass the source class to convert from (required) - * @param targetClass the target class to convert to (required) + * @param sourceType the source type to convert from (required) + * @param targetType the target type to convert to (required) * @return the executor that can execute instance type conversion, never null * @throws ConversionExecutorNotFoundException when no suitable conversion executor could be found */ - public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) + public ConversionExecutor getConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType) throws ConversionExecutorNotFoundException; /** * Get a ConversionExecutor that that converts objects from S to T with a custom converter. * The returned ConversionExecutor is thread-safe and may safely be cached for use in client code. * @param converterId the id of the custom converter, which must be registered with this conversion service and - * capable of converting from sourceClass to targetClass (required) - * @param sourceClass the source class to convert from (required) - * @param targetClass the target class to convert to (required) + * capable of converting from sourceType to targetType (required) + * @param sourceType the source type to convert from (required) + * @param targetType the target type to convert to (required) * @return the executor that can execute instance type conversion, never null * @throws ConversionExecutorNotFoundException when no suitable conversion executor could be found */ - public ConversionExecutor getConversionExecutor(String converterId, Class sourceClass, - Class targetClass) throws ConversionExecutorNotFoundException; + public ConversionExecutor getConversionExecutor(String converterId, TypeDescriptor sourceType, + TypeDescriptor targetType) throws ConversionExecutorNotFoundException; /** - * Get a class by its alias. - * @return the class, or null if no such alias exists + * Get a type by its name; may be the fully-qualified class name or a registered alias. + * @return the class, or null if no such name exists */ - public Class getClassForAlias(String alias); + public Class getType(String name); } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..9620b75e0371a3c005aeb2175e58a1841e5c6df8 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -0,0 +1,193 @@ +package org.springframework.core.convert; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; + +import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.MethodParameter; +import org.springframework.util.Assert; + +/** + * Metadata about a retrieved value or value type. + * + * @author Keith Donald + */ +public class TypeDescriptor { + + private MethodParameter methodParameter; + + private Field field; + + private Annotation[] cachedFieldAnnotations; + + private Class type; + + public TypeDescriptor(Class type) { + this.type = type; + } + + /** + * Create a new descriptor for a method or constructor parameter. + * + * @param methodParameter the MethodParameter to wrap + */ + public TypeDescriptor(MethodParameter methodParameter) { + Assert.notNull(methodParameter, "MethodParameter must not be null"); + this.methodParameter = methodParameter; + } + + /** + * Create a new descriptor for a field. Considers the dependency as 'eager'. + * + * @param field the field to wrap + */ + public TypeDescriptor(Field field) { + Assert.notNull(field, "Field must not be null"); + this.field = field; + } + + /** + * Determine the declared (non-generic) type of the wrapped parameter/field. + * + * @return the declared type (never null) + */ + public Class getType() { + if (type != null) { + return type; + } else if (field != null) { + return field.getType(); + } else { + return methodParameter.getParameterType(); + } + } + + public Class getWrapperTypeIfPrimitive() { + Class type = getType(); + 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; + } + } + + public String getName() { + return getType().getName(); + } + + public boolean isArray() { + return getType().isArray(); + } + + public Class getElementType() { + return isArray() ? getArrayComponentType() : getCollectionElementType(); + } + + public Class getArrayComponentType() { + return getType().getComponentType(); + } + + public boolean isInstance(Object source) { + return getType().isInstance(source); + } + + + /** + * Determine the generic element type of the wrapped Collection parameter/field, if any. + * + * @return the generic type, or null if none + */ + public Class getCollectionElementType() { + if (type != null) { + return GenericCollectionTypeResolver.getCollectionType((Class) type); + } else if (field != null) { + return GenericCollectionTypeResolver.getCollectionFieldType(field); + } else { + return GenericCollectionTypeResolver.getCollectionParameterType(methodParameter); + } + } + + /** + * Determine the generic key type of the wrapped Map parameter/field, if any. + * + * @return the generic type, or null if none + */ + public Class getMapKeyType() { + return (field != null ? GenericCollectionTypeResolver.getMapKeyFieldType(field) : GenericCollectionTypeResolver + .getMapKeyParameterType(methodParameter)); + } + + /** + * Determine the generic value type of the wrapped Map parameter/field, if any. + * + * @return the generic type, or null if none + */ + public Class getMapValueType() { + return (field != null ? GenericCollectionTypeResolver.getMapValueFieldType(field) + : GenericCollectionTypeResolver.getMapValueParameterType(methodParameter)); + } + + /** + * Obtain the annotations associated with the wrapped parameter/field, if any. + */ + public Annotation[] getAnnotations() { + if (field != null) { + if (cachedFieldAnnotations == null) { + cachedFieldAnnotations = field.getAnnotations(); + } + return cachedFieldAnnotations; + } else { + return methodParameter.getParameterAnnotations(); + } + } + + /** + * Return the wrapped MethodParameter, if any. + *

+ * Note: Either MethodParameter or Field is available. + * + * @return the MethodParameter, or null if none + */ + public MethodParameter getMethodParameter() { + return methodParameter; + } + + /** + * Return the wrapped Field, if any. + *

+ * Note: Either MethodParameter or Field is available. + * + * @return the Field, or null if none + */ + public Field getField() { + return field; + } + + public boolean isCollection() { + return Collection.class.isAssignableFrom(getType()); + } + + public boolean isAbstractClass() { + return !getType().isInterface() && Modifier.isAbstract(getType().getModifiers()); + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/TypedValue.java b/org.springframework.core/src/main/java/org/springframework/core/convert/TypedValue.java new file mode 100644 index 0000000000000000000000000000000000000000..ebdbe93467cb565a22e13d9c67c4da2a0bc81922 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/TypedValue.java @@ -0,0 +1,38 @@ +package org.springframework.core.convert; + +/** + * A value retrieved from some location such as a field access or getter invocation. + * + * @author Keith Donald + */ +public class TypedValue { + + private final Object value; + + private final TypeDescriptor typeDescriptor; + + /** + * Creates a typed value. + * @param value the actual value (may be null) + * @param typeDescriptor the value type descriptor (may be null) + */ + public TypedValue(Object value, TypeDescriptor typeDescriptor) { + this.value = value; + this.typeDescriptor = typeDescriptor; + } + + /** + * The actual value. May be null. + */ + public Object getValue() { + return value; + } + + /** + * Provides additional type context about the value. May be null. + */ + public TypeDescriptor getTypeDescriptor() { + return typeDescriptor; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterInfo.java b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..24b79daa7891d8a18d7b7e792beb2596cfd815a4 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterInfo.java @@ -0,0 +1,9 @@ +package org.springframework.core.convert.converter; + +public interface ConverterInfo { + + public Class getSourceType(); + + public Class getTargetType(); + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/AbstractCollectionConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/AbstractCollectionConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..2a1acc086a041f38f1d4a93607f273bf38833629 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/AbstractCollectionConverter.java @@ -0,0 +1,57 @@ +package org.springframework.core.convert.service; + +import org.springframework.core.convert.ConversionExecutionException; +import org.springframework.core.convert.ConversionExecutor; +import org.springframework.core.convert.TypeDescriptor; + +abstract class AbstractCollectionConverter implements ConversionExecutor { + + private TypeDescriptor sourceCollectionType; + + private TypeDescriptor targetCollectionType; + + private GenericConversionService conversionService; + + private ConversionExecutor elementConverter; + + public AbstractCollectionConverter(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, GenericConversionService conversionService) { + this.sourceCollectionType = sourceCollectionType; + this.targetCollectionType = targetCollectionType; + this.conversionService = conversionService; + this.elementConverter = createElementConverter(); + } + + private ConversionExecutor createElementConverter() { + Class sourceElementType = getSourceType().getElementType(); + Class targetElementType = getTargetType().getElementType(); + return (sourceElementType != null && targetElementType != null) ? conversionService.getElementConverter(sourceElementType, targetElementType) : null; + } + + protected TypeDescriptor getSourceType() { + return sourceCollectionType; + } + + protected TypeDescriptor getTargetType() { + return targetCollectionType; + } + + protected GenericConversionService getConversionService() { + return conversionService; + } + + protected ConversionExecutor getElementConverter() { + return elementConverter; + } + + @Override + public Object execute(Object source) throws ConversionExecutionException { + try { + return doExecute(source); + } catch (Exception e) { + throw new ConversionExecutionException(source, sourceCollectionType, targetCollectionType, e); + } + } + + protected abstract Object doExecute(Object sourceCollection) throws Exception; + +} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java index 072bc5292c4a79071f0dedbf6b2e621c8548acd8..89197a537e76688c63a3794a3070cb18b8bbb537 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToArray.java @@ -17,9 +17,8 @@ package org.springframework.core.convert.service; import java.lang.reflect.Array; -import org.springframework.core.convert.ConversionExecutor; import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperConverter; +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 @@ -28,49 +27,20 @@ import org.springframework.core.convert.converter.SuperConverter; * * @author Keith Donald */ -@SuppressWarnings("unchecked") -class ArrayToArray implements SuperConverter { +class ArrayToArray extends AbstractCollectionConverter { - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new array-to-array converter. - * @param conversionService the service to use to lookup conversion executors for individual array elements - * dynamically - */ - public ArrayToArray(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new array-to-array converter. - * @param elementConverter a specific conversion executor to use to convert elements in the source array to elements - * in the target array. - */ - public ArrayToArray(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; + public ArrayToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetArrayType, GenericConversionService conversionService) { + super(sourceArrayType, targetArrayType, conversionService); } - public Object convert(Object source, Class targetClass) throws Exception { - Class sourceComponentType = source.getClass().getComponentType(); - Class targetComponentType = targetClass.getComponentType(); - int length = Array.getLength(source); - Object targetArray = Array.newInstance(targetComponentType, length); - ConversionExecutor converter = getElementConverter(sourceComponentType, targetComponentType); + public Object doExecute(Object sourceArray) throws Exception { + int length = Array.getLength(sourceArray); + Object targetArray = Array.newInstance(getTargetType().getElementType(), length); for (int i = 0; i < length; i++) { - Object value = Array.get(source, i); - Array.set(targetArray, i, converter.execute(value)); + Object value = Array.get(sourceArray, i); + Array.set(targetArray, i, getElementConverter().execute(value)); } return targetArray; } - private ConversionExecutor getElementConverter(Class sourceComponentType, Class targetComponentType) { - if (elementConverter != null) { - return elementConverter; - } else { - return conversionService.getConversionExecutor(sourceComponentType, targetComponentType); - } - } } diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java index 869c8f4b404af52258973b55e6817411ba1323bf..a8cba46358816b606eb004faea46c85413cfbd78 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ArrayToCollection.java @@ -18,12 +18,10 @@ package org.springframework.core.convert.service; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.util.Collection; -import java.util.Iterator; -import org.springframework.core.GenericCollectionTypeResolver; import org.springframework.core.convert.ConversionExecutor; import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperTwoWayConverter; +import org.springframework.core.convert.TypeDescriptor; /** * Special converter that converts from a source array to a target collection. Supports the selection of an @@ -38,38 +36,23 @@ import org.springframework.core.convert.converter.SuperTwoWayConverter; * * @author Keith Donald */ -@SuppressWarnings("unchecked") -class ArrayToCollection implements SuperTwoWayConverter { +class ArrayToCollection extends AbstractCollectionConverter { - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new array to collection converter. - * @param conversionService the conversion service to use to lookup the converter to apply to array elements added - * to the target collection - */ - public ArrayToCollection(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new array to collection converter. - * @param elementConverter A specific converter to use on array elements when adding them to the target collection - */ - public ArrayToCollection(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; + public ArrayToCollection(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType, + GenericConversionService conversionService) { + super(sourceArrayType, targetCollectionType, conversionService); } - public Object convert(Object source, Class targetClass) throws Exception { - Class implClass = CollectionConversionUtils.getImpl(targetClass); + @Override + @SuppressWarnings("unchecked") + protected Object doExecute(Object sourceArray) throws Exception { + Class implClass = CollectionConversionUtils.getImpl(getTargetType().getType()); Constructor constructor = implClass.getConstructor((Class[]) null); Collection collection = (Collection) constructor.newInstance((Object[]) null); - ConversionExecutor converter = getArrayElementConverter(source, targetClass); - int length = Array.getLength(source); + int length = Array.getLength(sourceArray); + ConversionExecutor converter = getElementConverter(); for (int i = 0; i < length; i++) { - Object value = Array.get(source, i); + Object value = Array.get(sourceArray, i); if (converter != null) { value = converter.execute(value); } @@ -78,38 +61,4 @@ class ArrayToCollection implements SuperTwoWayConverter { return collection; } - public Object convertBack(Object target, Class sourceClass) throws Exception { - Collection collection = (Collection) target; - Class elementType = sourceClass.getComponentType(); - Object array = Array.newInstance(elementType, collection.size()); - int i = 0; - for (Iterator it = collection.iterator(); it.hasNext(); i++) { - Object value = it.next(); - if (value != null) { - ConversionExecutor converter; - if (elementConverter != null) { - converter = elementConverter; - } else { - converter = conversionService.getConversionExecutor(value.getClass(), elementType); - } - value = converter.execute(value); - } - Array.set(array, i, value); - } - return array; - } - - private ConversionExecutor getArrayElementConverter(Object source, Class targetClass) { - if (elementConverter != null) { - return elementConverter; - } else { - Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass); - if (elementType != null) { - Class componentType = source.getClass().getComponentType(); - return conversionService.getConversionExecutor(componentType, elementType); - } - return null; - } - } - } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java index b690a1e725efc0ba6fdcc34e3ec411a7fad42ba7..09df14f9e4dae8416c4450f6fc90430794e2c448 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToArray.java @@ -21,7 +21,7 @@ import java.util.Iterator; import org.springframework.core.convert.ConversionExecutor; import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperConverter; +import org.springframework.core.convert.TypeDescriptor; /** * Special converter that converts from a source array to a target collection. Supports the selection of an @@ -36,53 +36,29 @@ import org.springframework.core.convert.converter.SuperConverter; * * @author Keith Donald */ -@SuppressWarnings("unchecked") -class CollectionToArray implements SuperConverter { +class CollectionToArray extends AbstractCollectionConverter { - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new array to collection converter. - * @param conversionService the conversion service to use to lookup the converter to apply to array elements added - * to the target collection - */ - public CollectionToArray(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new array to collection converter. - * @param elementConverter A specific converter to use on array elements when adding them to the target collection - */ - public CollectionToArray(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; + public CollectionToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType, + GenericConversionService conversionService) { + super(sourceArrayType, targetCollectionType, conversionService); } - public Object convert(Object source, Class targetClass) throws Exception { - Collection collection = (Collection) source; - Object array = Array.newInstance(targetClass.getComponentType(), collection.size()); + @Override + protected Object doExecute(Object source) throws Exception { + Collection collection = (Collection) source; + Class targetComponentType = getTargetType().getElementType(); + Object array = Array.newInstance(targetComponentType, collection.size()); int i = 0; - for (Iterator it = collection.iterator(); it.hasNext(); i++) { + ConversionExecutor converter = getElementConverter(); + for (Iterator it = collection.iterator(); it.hasNext(); i++) { Object value = it.next(); - if (value != null) { - ConversionExecutor converter; - if (elementConverter != null) { - converter = elementConverter; - } else { - converter = conversionService.getConversionExecutor(value.getClass(), targetClass - .getComponentType()); - } - value = converter.execute(value); + if (converter == null) { + converter = getConversionService().getElementConverter(value.getClass(), targetComponentType); } + value = converter.execute(value); Array.set(array, i, value); } return array; } - public Object convertBack(Object target) throws Exception { - throw new UnsupportedOperationException("Should never be called"); - } - } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java index 0effacd8ee3a53ed9dc83987bd6e239e5ced6ad2..954a7664981b53ced812aca9f2c552c97f1771fb 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/CollectionToCollection.java @@ -20,66 +20,45 @@ import java.util.Iterator; import org.springframework.core.GenericCollectionTypeResolver; import org.springframework.core.convert.ConversionExecutor; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperConverter; +import org.springframework.core.convert.TypeDescriptor; /** * A converter that can convert from one collection type to another. * * @author Keith Donald */ -@SuppressWarnings("unchecked") -class CollectionToCollection implements SuperConverter { - - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new collection-to-collection converter - * @param conversionService the conversion service to use to convert collection elements to add to the target - * collection - */ - public CollectionToCollection(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new collection-to-collection converter - * @param elementConverter a specific converter to use to convert collection elements added to the target collection - */ - public CollectionToCollection(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; +class CollectionToCollection extends AbstractCollectionConverter { + + public CollectionToCollection(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, + GenericConversionService conversionService) { + super(sourceCollectionType, targetCollectionType, conversionService); } - public Collection convert(Collection source, Class targetClass) throws Exception { - Class implClass = CollectionConversionUtils.getImpl(targetClass); + @Override + @SuppressWarnings("unchecked") + protected Object doExecute(Object source) throws Exception { + Collection sourceCollection = (Collection) source; + Class targetCollectionType = getTargetType().getType(); + Class implClass = CollectionConversionUtils.getImpl(targetCollectionType); Collection targetCollection = (Collection) implClass.getConstructor((Class[]) null) .newInstance((Object[]) null); - ConversionExecutor elementConverter = getElementConverter(source, targetClass); - Collection sourceCollection = (Collection) source; + ConversionExecutor elementConverter = getElementConverter(); + Class elementType; + if (elementConverter == null) { + elementType = GenericCollectionTypeResolver.getCollectionType(targetCollectionType); + } else { + elementType = null; + } Iterator it = sourceCollection.iterator(); while (it.hasNext()) { Object value = it.next(); - if (elementConverter != null) { - value = elementConverter.execute(value); + if (elementConverter == null && elementType != null) { + elementConverter = getConversionService().getElementConverter(value.getClass(), elementType); } + value = elementConverter.execute(value); targetCollection.add(value); } return targetCollection; } - - private ConversionExecutor getElementConverter(Object source, Class targetClass) { - if (elementConverter != null) { - return elementConverter; - } else { - Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass); - if (elementType != null) { - Class componentType = source.getClass().getComponentType(); - return conversionService.getConversionExecutor(componentType, elementType); - } - return null; - } - } - + } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/DefaultConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/DefaultConversionService.java index 220540f4e0628fb983ecdc51253c895da7453001..07326f722ab4a02e15dc7745ca044497829db266 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/DefaultConversionService.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/DefaultConversionService.java @@ -67,9 +67,6 @@ public class DefaultConversionService extends GenericConversionService { addConverter(new StringToLocale()); addConverter(new StringToEnum()); addConverter(new NumberToNumber()); - // TODO probably don't allow these to be customized, or at least make public - addConverter(new ObjectToCollection(this)); - addConverter(new CollectionToCollection(this)); } protected void addDefaultAliases() { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java index 57582d99916e59700e1a44bd317d33c06e9d0792..50935ff8681c8be646ad8601be749897431cf3af 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java @@ -32,6 +32,8 @@ import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionExecutor; import org.springframework.core.convert.ConversionExecutorNotFoundException; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.TypedValue; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.SuperConverter; import org.springframework.core.convert.converter.SuperTwoWayConverter; @@ -149,9 +151,9 @@ public class GenericConversionService implements ConversionService { } /** - * Add a convenient alias for the target type. {@link #getClassForAlias(String)} can then be used to lookup the type + * Add a convenient alias for the target type. {@link #getType(String)} can then be used to lookup the type * given the alias. - * @see #getClassForAlias(String) + * @see #getType(String) */ public void addAlias(String alias, Class targetType) { aliasMap.put(alias, targetType); @@ -159,225 +161,85 @@ public class GenericConversionService implements ConversionService { // implementing ConversionService - public Object executeConversion(Object source, Class targetClass) throws ConversionExecutorNotFoundException, + public boolean canConvert(TypedValue source, TypeDescriptor targetType) { + return false; + } + + public Object executeConversion(TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, ConversionException { - return getConversionExecutor(source.getClass(), targetClass).execute(source); + return getConversionExecutor(source.getTypeDescriptor(), targetType).execute(source.getValue()); } - public Object executeConversion(String converterId, Object source, Class targetClass) + public Object executeConversion(String converterId, TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, ConversionException { - return getConversionExecutor(converterId, source.getClass(), targetClass).execute(source); + return getConversionExecutor(converterId, source.getTypeDescriptor(), targetType).execute(source.getValue()); } - public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) + public ConversionExecutor getConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType) throws ConversionExecutorNotFoundException { - Assert.notNull(sourceClass, "The source class to convert from is required"); - Assert.notNull(targetClass, "The target class to convert to is required"); - if (targetClass.isAssignableFrom(sourceClass)) { - return new StaticConversionExecutor(sourceClass, targetClass, new NoOpConverter()); - } - sourceClass = convertToWrapperClassIfNecessary(sourceClass); - targetClass = convertToWrapperClassIfNecessary(targetClass); + Assert.notNull(sourceType, "The sourceType to convert from is required"); + Assert.notNull(targetType, "The targetType to convert to is required"); // special handling for arrays since they are not indexable classes - if (sourceClass.isArray()) { - if (targetClass.isArray()) { - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToArray(this)); - } else if (Collection.class.isAssignableFrom(targetClass)) { - if (!targetClass.isInterface() && Modifier.isAbstract(targetClass.getModifiers())) { - throw new IllegalArgumentException("Conversion target class [" + targetClass.getName() + if (sourceType.isArray()) { + if (targetType.isArray()) { + return new ArrayToArray(sourceType, targetType, this); + } else if (targetType.isCollection()) { + if (targetType.isAbstractClass()) { + throw new IllegalArgumentException("Conversion target class [" + targetType.getName() + "] is invalid; cannot convert to abstract collection types--" + "request an interface or concrete implementation instead"); } - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToCollection(this)); + return new ArrayToCollection(sourceType, targetType, this); + } + } + if (targetType.isArray()) { + if (sourceType.isCollection()) { + return new CollectionToArray(sourceType, targetType, this); + } else { + throw new UnsupportedOperationException("Object to Array not yet supported"); } } - if (targetClass.isArray()) { - if (Collection.class.isAssignableFrom(sourceClass)) { - SuperConverter collectionToArray = new ReverseSuperConverter(new ArrayToCollection(this)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, collectionToArray); + if (sourceType.isCollection()) { + if (targetType.isCollection()) { + return new CollectionToCollection(sourceType, targetType, this); } else { - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ObjectToArray(this)); + throw new UnsupportedOperationException("Object to collection not yet supported"); } } + Class sourceClass = sourceType.getWrapperTypeIfPrimitive(); + Class targetClass = targetType.getWrapperTypeIfPrimitive(); Converter converter = findRegisteredConverter(sourceClass, targetClass); if (converter != null) { // we found a converter - return new StaticConversionExecutor(sourceClass, targetClass, converter); + return new StaticConversionExecutor(sourceType, targetType, converter); } else { SuperConverter superConverter = findRegisteredSuperConverter(sourceClass, targetClass); if (superConverter != null) { - return new StaticSuperConversionExecutor(sourceClass, targetClass, superConverter); + return new StaticSuperConversionExecutor(sourceType, targetType, superConverter); } if (parent != null) { // try the parent - return parent.getConversionExecutor(sourceClass, targetClass); + return parent.getConversionExecutor(sourceType, targetType); } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "No ConversionExecutor found for converting from sourceClass [" + sourceClass.getName() - + "] to target class [" + targetClass.getName() + "]"); + throw new ConversionExecutorNotFoundException(sourceType, targetType, + "No ConversionExecutor found for converting from sourceType [" + sourceType.getName() + + "] to targetType [" + targetType.getName() + "]"); } } } - public ConversionExecutor getConversionExecutor(String id, Class sourceClass, Class targetClass) - throws ConversionExecutorNotFoundException { - Assert.hasText(id, "The id of the custom converter is required"); - Assert.notNull(sourceClass, "The source class to convert from is required"); - Assert.notNull(targetClass, "The target class to convert to is required"); - Converter converter = (Converter) customConverters.get(id); - if (converter == null) { - if (parent != null) { - return parent.getConversionExecutor(id, sourceClass, targetClass); - } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "No custom Converter found with id '" + id + "' for converting from sourceClass [" - + sourceClass.getName() + "] to targetClass [" + targetClass.getName() + "]"); - } - } - sourceClass = convertToWrapperClassIfNecessary(sourceClass); - targetClass = convertToWrapperClassIfNecessary(targetClass); - // TODO Not optimal getting this each time - List typeInfo = getRequiredTypeInfo(converter); - Class converterSourceClass = (Class) typeInfo.get(0); - Class converterTargetClass = (Class) typeInfo.get(1); - if (sourceClass.isArray()) { - Class sourceComponentType = sourceClass.getComponentType(); - if (targetClass.isArray()) { - Class targetComponentType = targetClass.getComponentType(); - if (converterSourceClass.isAssignableFrom(sourceComponentType)) { - if (!converterTargetClass.equals(targetComponentType)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id - + "' cannot convert from an array storing elements of type [" - + sourceComponentType.getName() + "] to an array of storing elements of type [" - + targetComponentType.getName() + "]"); - } - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, - targetComponentType, converter); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToArray( - elementConverter)); - } else if (converterTargetClass.isAssignableFrom(sourceComponentType)) { - if (!converterSourceClass.equals(targetComponentType)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id - + "' cannot convert from an array storing elements of type [" - + sourceComponentType.getName() + "] to an array of storing elements of type [" - + targetComponentType.getName() + "]"); - } - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, - targetComponentType, new ReverseConverter(converter)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToArray( - elementConverter)); - } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id - + "' cannot convert from an array storing elements of type [" - + sourceComponentType.getName() + "] to an array storing elements of type [" - + targetComponentType.getName() + "]"); - } - } else if (Collection.class.isAssignableFrom(targetClass)) { - if (!targetClass.isInterface() && Modifier.isAbstract(targetClass.getModifiers())) { - throw new IllegalArgumentException("Conversion target class [" + targetClass.getName() - + "] is invalid; cannot convert to abstract collection types--" - + "request an interface or concrete implementation instead"); - } - if (converterSourceClass.isAssignableFrom(sourceComponentType)) { - // type erasure has prevented us from getting the concrete type, this is best we can do for now - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, - converterTargetClass, converter); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToCollection( - elementConverter)); - } else if (converterTargetClass.isAssignableFrom(sourceComponentType)) { - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType, - converterSourceClass, new ReverseConverter(converter)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ArrayToCollection( - elementConverter)); - } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id - + "' cannot convert from array an storing elements type [" - + sourceComponentType.getName() + "] to a collection of type [" - + targetClass.getName() + "]"); - } - } - } - if (targetClass.isArray()) { - Class targetComponentType = targetClass.getComponentType(); - if (Collection.class.isAssignableFrom(sourceClass)) { - // type erasure limits us here as well - if (converterTargetClass.equals(targetComponentType)) { - ConversionExecutor elementConverter = new StaticConversionExecutor(converterSourceClass, - targetComponentType, converter); - SuperConverter collectionToArray = new ReverseSuperConverter( - new ArrayToCollection(elementConverter)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, collectionToArray); - } else if (converterSourceClass.equals(targetComponentType)) { - ConversionExecutor elementConverter = new StaticConversionExecutor(converterTargetClass, - targetComponentType, new ReverseConverter(converter)); - SuperConverter collectionToArray = new ReverseSuperConverter( - new ArrayToCollection(elementConverter)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, collectionToArray); - } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id + "' cannot convert from collection of type [" - + sourceClass.getName() + "] to an array storing elements of type [" - + targetComponentType.getName() + "]"); - } - } else { - if (converterSourceClass.isAssignableFrom(sourceClass)) { - if (!converterTargetClass.equals(targetComponentType)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id + "' cannot convert from sourceClass [" - + sourceClass.getName() + "] to array holding elements of type [" - + targetComponentType.getName() + "]"); - } - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceClass, - targetComponentType, converter); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ObjectToArray( - elementConverter)); - } else if (converterTargetClass.isAssignableFrom(sourceClass)) { - if (!converterSourceClass.equals(targetComponentType)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, - "Custom Converter with id '" + id + "' cannot convert from sourceClass [" - + sourceClass.getName() + "] to array holding elements of type [" - + targetComponentType.getName() + "]"); - } - ConversionExecutor elementConverter = new StaticConversionExecutor(sourceClass, - targetComponentType, new ReverseConverter(converter)); - return new StaticSuperConversionExecutor(sourceClass, targetClass, new ObjectToArray( - elementConverter)); - } - } - } - // TODO look to factor some of this duplicated code here and above out a bit - if (converterSourceClass.isAssignableFrom(sourceClass)) { - if (!converterTargetClass.equals(targetClass)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, "Custom Converter with id '" - + id + "' cannot convert from sourceClass [" + sourceClass.getName() + "] to targetClass [" - + targetClass.getName() + "]"); - } - return new StaticConversionExecutor(sourceClass, targetClass, converter); - } else if (converterTargetClass.isAssignableFrom(sourceClass)) { - if (!converterSourceClass.equals(targetClass)) { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, "Custom Converter with id '" - + id + "' cannot convert from sourceClass [" + sourceClass.getName() + "] to targetClass [" - + targetClass.getName() + "]"); - } - return new StaticConversionExecutor(sourceClass, targetClass, new ReverseConverter(converter)); - } else { - throw new ConversionExecutorNotFoundException(sourceClass, targetClass, "Custom Converter with id '" + id - + "' cannot convert from sourceClass [" + sourceClass.getName() + "] to targetClass [" - + targetClass.getName() + "]"); - } + public ConversionExecutor getConversionExecutor(String converterId, TypeDescriptor sourceType, + TypeDescriptor targetType) throws ConversionExecutorNotFoundException { + throw new UnsupportedOperationException("Not yet implemented"); } - public Class getClassForAlias(String name) throws IllegalArgumentException { + public Class getType(String name) throws IllegalArgumentException { Class clazz = (Class) aliasMap.get(name); if (clazz != null) { return clazz; } else { if (parent != null) { - return parent.getClassForAlias(name); + return parent.getType(name); } else { return null; } @@ -444,32 +306,6 @@ public class GenericConversionService implements ConversionService { return sourceMap; } - private Class convertToWrapperClassIfNecessary(Class targetType) { - if (targetType.isPrimitive()) { - if (targetType.equals(int.class)) { - return Integer.class; - } else if (targetType.equals(short.class)) { - return Short.class; - } else if (targetType.equals(long.class)) { - return Long.class; - } else if (targetType.equals(float.class)) { - return Float.class; - } else if (targetType.equals(double.class)) { - return Double.class; - } else if (targetType.equals(byte.class)) { - return Byte.class; - } else if (targetType.equals(boolean.class)) { - return Boolean.class; - } else if (targetType.equals(char.class)) { - return Character.class; - } else { - throw new IllegalStateException("Should never happen - primitive type is not a primitive?"); - } - } else { - return targetType; - } - } - private Converter findRegisteredConverter(Class sourceClass, Class targetClass) { if (sourceClass.isInterface()) { LinkedList classQueue = new LinkedList(); @@ -604,4 +440,8 @@ public class GenericConversionService implements ConversionService { } } + public ConversionExecutor getElementConverter(Class sourceElementType, Class targetElementType) { + return getConversionExecutor(new TypeDescriptor(sourceElementType), new TypeDescriptor(targetElementType)); + } + } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToArray.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToArray.java deleted file mode 100644 index 897e8ef47c2cfdc22cce01a482cd93d592ec7540..0000000000000000000000000000000000000000 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToArray.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.core.convert.service; - -import java.lang.reflect.Array; - -import org.springframework.core.convert.ConversionExecutor; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperConverter; - -/** - * Special converter that converts an object to an single-element array. Mainly used internally by - * {@link ConversionService} implementations. - * - * @author Keith Donald - */ -@SuppressWarnings("unchecked") -class ObjectToArray implements SuperConverter { - - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new object to array converter. - * @param conversionService the conversion service to resolve the converter to use to convert the object added to - * the target array. - */ - public ObjectToArray(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new object to array converter. - * @param elementConverter a specific converter to use to convert the object added to the target array. - */ - public ObjectToArray(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; - } - - public Object convert(Object source, Class targetClass) throws Exception { - Class componentType = targetClass.getComponentType(); - Object array = Array.newInstance(componentType, 1); - ConversionExecutor converter; - if (elementConverter != null) { - converter = elementConverter; - } else { - converter = conversionService.getConversionExecutor(source.getClass(), componentType); - } - Array.set(array, 0, converter.execute(source)); - return array; - } - -} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToCollection.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToCollection.java deleted file mode 100644 index 9620624b2ecd9dee67298772be54a55fba277676..0000000000000000000000000000000000000000 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/ObjectToCollection.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2004-2009 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.core.convert.service; - -import java.lang.reflect.Constructor; -import java.util.Collection; - -import org.springframework.core.GenericCollectionTypeResolver; -import org.springframework.core.convert.ConversionExecutor; -import org.springframework.core.convert.ConversionService; -import org.springframework.core.convert.converter.SuperConverter; - -/** - * Special two-way converter that converts an object to an single-element collection. Supports type conversion of the - * individual element with parameterized collection implementations. - * - * @author Keith Donald - */ -@SuppressWarnings("unchecked") -class ObjectToCollection implements SuperConverter { - - private ConversionService conversionService; - - private ConversionExecutor elementConverter; - - /** - * Creates a new object to collection converter - * @param conversionService the conversion service to lookup the converter to use to convert an object when adding - * it to a target collection - */ - public ObjectToCollection(ConversionService conversionService) { - this.conversionService = conversionService; - } - - /** - * Creates a new object to collection converter - * @param elementConverter a specific converter to execute on an object when adding it to a target collection - */ - public ObjectToCollection(ConversionExecutor elementConverter) { - this.elementConverter = elementConverter; - } - - public Collection convert(Object source, Class targetClass) throws Exception { - Class implClass = CollectionConversionUtils.getImpl(targetClass); - Constructor constructor = implClass.getConstructor((Class[]) null); - Collection collection = (Collection) constructor.newInstance((Object[]) null); - ConversionExecutor converter = getElementConverter(source, targetClass); - Object value; - if (converter != null) { - value = converter.execute(source); - } else { - value = source; - } - collection.add(value); - return collection; - } - - private ConversionExecutor getElementConverter(Object source, Class targetClass) { - if (elementConverter != null) { - return elementConverter; - } else { - Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass); - if (elementType != null) { - Class componentType = source.getClass().getComponentType(); - return conversionService.getConversionExecutor(componentType, elementType); - } - return null; - } - } -} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java index ae94394e8198a7ab12cbbedabe699440941a67cc..b48203f7ca68198a6ffc7c6d4b704f28395fd09f 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java @@ -17,47 +17,44 @@ package org.springframework.core.convert.service; import org.springframework.core.convert.ConversionExecutionException; import org.springframework.core.convert.ConversionExecutor; +import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.style.ToStringCreator; -import org.springframework.util.Assert; -class StaticConversionExecutor implements ConversionExecutor { +class StaticConversionExecutor implements ConversionExecutor { - private final Class sourceClass; + private final TypeDescriptor sourceType; - private final Class targetClass; + private final TypeDescriptor targetType; - private final Converter converter; + private final Converter converter; - public StaticConversionExecutor(Class sourceClass, Class targetClass, Converter converter) { - Assert.notNull(sourceClass, "The source class is required"); - Assert.notNull(targetClass, "The target class is required"); - Assert.notNull(converter, "The converter is required"); - this.sourceClass = sourceClass; - this.targetClass = targetClass; + public StaticConversionExecutor(TypeDescriptor sourceClass, TypeDescriptor targetClass, Converter converter) { + this.sourceType = sourceClass; + this.targetType = targetClass; this.converter = converter; } - public Class getSourceClass() { - return sourceClass; + public TypeDescriptor getSourceType() { + return sourceType; } - public Class getTargetClass() { - return targetClass; + public TypeDescriptor getTargetType() { + return targetType; } - public T execute(S source) throws ConversionExecutionException { + public Object execute(Object source) throws ConversionExecutionException { if (source == null) { return null; } - if (!sourceClass.isInstance(source)) { - throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), "Source object " - + source + " to convert is expected to be an instance of [" + getSourceClass().getName() + "]"); + if (sourceType != null && !sourceType.isInstance(source)) { + throw new ConversionExecutionException(source, getSourceType(), getTargetType(), "Source object " + + source + " to convert is expected to be an instance of [" + getSourceType().getName() + "]"); } try { return converter.convert(source); } catch (Exception e) { - throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), e); + throw new ConversionExecutionException(source, getSourceType(), getTargetType(), e); } } @@ -65,16 +62,16 @@ class StaticConversionExecutor implements ConversionExecutor { if (!(o instanceof StaticConversionExecutor)) { return false; } - StaticConversionExecutor other = (StaticConversionExecutor) o; - return sourceClass.equals(other.sourceClass) && targetClass.equals(other.targetClass); + StaticConversionExecutor other = (StaticConversionExecutor) o; + return sourceType.equals(other.sourceType) && targetType.equals(other.targetType); } public int hashCode() { - return sourceClass.hashCode() + targetClass.hashCode(); + return sourceType.hashCode() + targetType.hashCode(); } public String toString() { - return new ToStringCreator(this).append("sourceClass", sourceClass).append("targetClass", targetClass) + return new ToStringCreator(this).append("sourceClass", sourceType).append("targetClass", targetType) .toString(); } } \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java index 520ce9a48dcce7a2bc8f162eb26b74af50ed40bf..bf8c17c3aa1afc4087dd80ed0e4f28ea498c89fd 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java @@ -17,47 +17,37 @@ package org.springframework.core.convert.service; import org.springframework.core.convert.ConversionExecutionException; import org.springframework.core.convert.ConversionExecutor; +import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.SuperConverter; import org.springframework.core.style.ToStringCreator; import org.springframework.util.Assert; -class StaticSuperConversionExecutor implements ConversionExecutor { +class StaticSuperConversionExecutor implements ConversionExecutor { - private final Class sourceClass; + private final TypeDescriptor sourceType; - private final Class targetClass; + private final TypeDescriptor targetType; - private final SuperConverter converter; + private final SuperConverter converter; - public StaticSuperConversionExecutor(Class sourceClass, Class targetClass, SuperConverter converter) { - Assert.notNull(sourceClass, "The source class is required"); - Assert.notNull(targetClass, "The target class is required"); - Assert.notNull(converter, "The super converter is required"); - this.sourceClass = sourceClass; - this.targetClass = targetClass; + public StaticSuperConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType, SuperConverter converter) { + this.sourceType = sourceType; + this.targetType = targetType; this.converter = converter; } - public Class getSourceClass() { - return sourceClass; - } - - public Class getTargetClass() { - return targetClass; - } - - public T execute(S source) throws ConversionExecutionException { + public Object execute(Object source) throws ConversionExecutionException { if (source == null) { return null; } - if (!sourceClass.isInstance(source)) { - throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), "Source object " - + source + " to convert is expected to be an instance of [" + getSourceClass().getName() + "]"); + if (!sourceType.isInstance(source)) { + throw new ConversionExecutionException(source, sourceType, targetType, "Source object " + + source + " to convert is expected to be an instance of [" + sourceType.getName() + "]"); } try { - return converter.convert(source, targetClass); + return converter.convert(source, targetType.getType()); } catch (Exception e) { - throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), e); + throw new ConversionExecutionException(source, sourceType, targetType, e); } } @@ -65,16 +55,16 @@ class StaticSuperConversionExecutor implements ConversionExecutor { if (!(o instanceof StaticSuperConversionExecutor)) { return false; } - StaticSuperConversionExecutor other = (StaticSuperConversionExecutor) o; - return sourceClass.equals(other.sourceClass) && targetClass.equals(other.targetClass); + StaticSuperConversionExecutor other = (StaticSuperConversionExecutor) o; + return sourceType.equals(other.sourceType) && targetType.equals(other.targetType); } public int hashCode() { - return sourceClass.hashCode() + targetClass.hashCode(); + return sourceType.hashCode() + targetType.hashCode(); } public String toString() { - return new ToStringCreator(this).append("sourceClass", sourceClass).append("targetClass", targetClass) + return new ToStringCreator(this).append("sourceClass", sourceType).append("targetClass", targetType) .toString(); } } \ No newline at end of file diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/service/GenericConversionServiceTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/service/GenericConversionServiceTests.java index cfa499f7f0f9d32c30ccf70c5934f0ac79bcc3ab..48930ff00b9c110686e4914f59e4afe8974efb3d 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/service/GenericConversionServiceTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/service/GenericConversionServiceTests.java @@ -28,6 +28,8 @@ import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionExecutionException; import org.springframework.core.convert.ConversionExecutor; import org.springframework.core.convert.ConversionExecutorNotFoundException; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.TypedValue; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.NumberToNumber; import org.springframework.core.convert.converter.StringToEnum; @@ -37,47 +39,55 @@ public class GenericConversionServiceTests extends TestCase { private GenericConversionService service = new GenericConversionService(); + private TypedValue value(Object obj) { + return new TypedValue(obj, new TypeDescriptor(obj.getClass())); + } + + private TypeDescriptor type(Class clazz) { + return new TypeDescriptor(clazz); + } + public void testExecuteConversion() { service.addConverter(new StringToInteger()); - assertEquals(new Integer(3), service.executeConversion("3", Integer.class)); + assertEquals(new Integer(3), service.executeConversion(value("3"), type(Integer.class))); } public void testConverterConversionForwardIndex() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Integer.class)); Integer three = (Integer) executor.execute("3"); assertEquals(3, three.intValue()); } public void testConverterConversionReverseIndex() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(Integer.class, String.class); + ConversionExecutor executor = service.getConversionExecutor(type(Integer.class), type(String.class)); String threeString = (String) executor.execute(new Integer(3)); assertEquals("3", threeString); } public void testConversionExecutorNotFound() { try { - service.getConversionExecutor(String.class, Integer.class); + service.getConversionExecutor(type(String.class), type(Integer.class)); fail("Should have thrown an exception"); } catch (ConversionExecutorNotFoundException e) { } } public void testConversionCompatibleTypes() { - ArrayList source = new ArrayList(); - assertSame(source, service.getConversionExecutor(ArrayList.class, List.class).execute(source)); + String source = "foo"; + assertSame(source, service.getConversionExecutor(type(String.class), type(String.class)).execute(source)); } public void testConversionExecutorNullArgument() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Integer.class)); assertNull(executor.execute(null)); } public void testConversionExecutorWrongTypeArgument() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(Integer.class, String.class); + ConversionExecutor executor = service.getConversionExecutor(type(Integer.class), type(String.class)); try { executor.execute("BOGUS"); fail("Should have failed"); @@ -96,7 +106,7 @@ public class GenericConversionServiceTests extends TestCase { return target.toString(); } }); - ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Integer.class)); Integer result = (Integer) executor.execute("3"); assertEquals(new Integer(3), result); } @@ -112,7 +122,7 @@ public class GenericConversionServiceTests extends TestCase { } }); try { - ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Integer.class)); fail("Should have failed"); } catch (ConversionExecutorNotFoundException e) { @@ -121,14 +131,14 @@ public class GenericConversionServiceTests extends TestCase { public void testConversionObjectToPrimitive() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String.class, int.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(int.class)); Integer three = (Integer) executor.execute("3"); assertEquals(3, three.intValue()); } public void testConversionArrayToArray() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String[].class, Integer[].class); + ConversionExecutor executor = service.getConversionExecutor(type(String[].class), type(Integer[].class)); Integer[] result = (Integer[]) executor.execute(new String[] { "1", "2", "3" }); assertEquals(new Integer(1), result[0]); assertEquals(new Integer(2), result[1]); @@ -137,7 +147,7 @@ public class GenericConversionServiceTests extends TestCase { public void testConversionArrayToPrimitiveArray() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String[].class, int[].class); + ConversionExecutor executor = service.getConversionExecutor(type(String[].class), type(int[].class)); int[] result = (int[]) executor.execute(new String[] { "1", "2", "3" }); assertEquals(1, result[0]); assertEquals(2, result[1]); @@ -145,15 +155,23 @@ public class GenericConversionServiceTests extends TestCase { } public void testConversionArrayToListInterface() { - ConversionExecutor executor = service.getConversionExecutor(String[].class, List.class); + ConversionExecutor executor = service.getConversionExecutor(type(String[].class), type(List.class)); List result = (List) executor.execute(new String[] { "1", "2", "3" }); assertEquals("1", result.get(0)); assertEquals("2", result.get(1)); assertEquals("3", result.get(2)); } + public void testConversionArrayToListGenericTypeConversion() { + ConversionExecutor executor = service.getConversionExecutor(type(String[].class), type(List.class)); + List result = (List) executor.execute(new String[] { "1", "2", "3" }); + assertEquals(new Integer("1"), result.get(0)); + assertEquals(new Integer("2"), result.get(1)); + assertEquals(new Integer("3"), result.get(2)); + } + public void testConversionArrayToListImpl() { - ConversionExecutor executor = service.getConversionExecutor(String[].class, LinkedList.class); + ConversionExecutor executor = service.getConversionExecutor(type(String[].class), type(LinkedList.class)); LinkedList result = (LinkedList) executor.execute(new String[] { "1", "2", "3" }); assertEquals("1", result.get(0)); assertEquals("2", result.get(1)); @@ -162,14 +180,14 @@ public class GenericConversionServiceTests extends TestCase { public void testConversionArrayToAbstractList() { try { - service.getConversionExecutor(String[].class, AbstractList.class); + service.getConversionExecutor(type(String[].class), type(AbstractList.class)); } catch (IllegalArgumentException e) { } } public void testConversionListToArray() { - ConversionExecutor executor = service.getConversionExecutor(Collection.class, String[].class); + ConversionExecutor executor = service.getConversionExecutor(type(Collection.class), type(String[].class)); List list = new ArrayList(); list.add("1"); list.add("2"); @@ -182,7 +200,7 @@ public class GenericConversionServiceTests extends TestCase { public void testConversionListToArrayWithComponentConversion() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(Collection.class, Integer[].class); + ConversionExecutor executor = service.getConversionExecutor(type(Collection.class), type(Integer[].class)); List list = new ArrayList(); list.add("1"); list.add("2"); @@ -194,7 +212,7 @@ public class GenericConversionServiceTests extends TestCase { } public void testConversionObjectToArray() { - ConversionExecutor executor = service.getConversionExecutor(String.class, String[].class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(String[].class)); String[] result = (String[]) executor.execute("1,2,3"); assertEquals(1, result.length); assertEquals("1,2,3", result[0]); @@ -202,7 +220,7 @@ public class GenericConversionServiceTests extends TestCase { public void testConversionObjectToArrayWithElementConversion() { service.addConverter(new StringToInteger()); - ConversionExecutor executor = service.getConversionExecutor(String.class, Integer[].class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Integer[].class)); Integer[] result = (Integer[]) executor.execute("123"); assertEquals(1, result.length); assertEquals(new Integer(123), result[0]); @@ -214,19 +232,19 @@ public class GenericConversionServiceTests extends TestCase { public void testSuperConverterConversionForwardIndex() { service.addConverter(new StringToEnum()); - ConversionExecutor executor = service.getConversionExecutor(String.class, FooEnum.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(FooEnum.class)); assertEquals(FooEnum.BAR, executor.execute("BAR")); } public void testSuperTwoWayConverterConversionReverseIndex() { service.addConverter(new StringToEnum()); - ConversionExecutor executor = service.getConversionExecutor(FooEnum.class, String.class); + ConversionExecutor executor = service.getConversionExecutor(type(FooEnum.class), type(String.class)); assertEquals("BAR", executor.execute(FooEnum.BAR)); } public void testSuperConverterConversionNotConvertibleAbstractType() { service.addConverter(new StringToEnum()); - ConversionExecutor executor = service.getConversionExecutor(String.class, Enum.class); + ConversionExecutor executor = service.getConversionExecutor(type(String.class), type(Enum.class)); try { executor.execute("WHATEV"); fail("Should have failed"); @@ -258,7 +276,7 @@ public class GenericConversionServiceTests extends TestCase { return 0; } }; - ConversionExecutor executor = service.getConversionExecutor(Integer.class, customNumber.getClass()); + ConversionExecutor executor = service.getConversionExecutor(type(Integer.class), type(customNumber.getClass())); try { executor.execute(3); fail("Should have failed"); @@ -286,13 +304,13 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionForwardIndex() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", String.class, Principal.class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(String.class), type(Principal.class)); assertEquals("keith", ((Principal) executor.execute("keith")).getName()); } public void testCustomConverterConversionReverseIndex() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", Principal.class, String.class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(Principal.class), type(String.class)); assertEquals("keith", executor.execute(new Principal() { public String getName() { return "keith"; @@ -302,14 +320,14 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionForSameType() { service.addConverter("trimmer", new Trimmer()); - ConversionExecutor executor = service.getConversionExecutor("trimmer", String.class, String.class); + ConversionExecutor executor = service.getConversionExecutor("trimmer", type(String.class), type(String.class)); assertEquals("a string", executor.execute("a string ")); } public void testCustomConverterLookupNotCompatibleSource() { service.addConverter("trimmer", new Trimmer()); try { - service.getConversionExecutor("trimmer", Object.class, String.class); + service.getConversionExecutor("trimmer", type(Object.class), type(String.class)); fail("Should have failed"); } catch (ConversionException e) { @@ -319,7 +337,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupNotCompatibleTarget() { service.addConverter("trimmer", new Trimmer()); try { - service.getConversionExecutor("trimmer", String.class, Object.class); + service.getConversionExecutor("trimmer", type(String.class), type(Object.class)); } catch (ConversionException e) { } @@ -328,7 +346,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupNotCompatibleTargetReverse() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", Principal.class, Integer.class); + service.getConversionExecutor("princy", type(Principal.class), type(Integer.class)); } catch (ConversionException e) { } @@ -336,7 +354,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionArrayToArray() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", String[].class, Principal[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(String[].class), type(Principal[].class)); Principal[] p = (Principal[]) executor.execute(new String[] { "princy1", "princy2" }); assertEquals("princy1", p[0].getName()); assertEquals("princy2", p[1].getName()); @@ -344,7 +362,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionArrayToArrayReverse() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", Principal[].class, String[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(Principal[].class), type(String[].class)); final Principal princy1 = new Principal() { public String getName() { return "princy1"; @@ -363,7 +381,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupArrayToArrayBogusSource() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", Integer[].class, Principal[].class); + service.getConversionExecutor("princy", type(Integer[].class), type(Principal[].class)); fail("Should have failed"); } catch (ConversionExecutorNotFoundException e) { } @@ -372,7 +390,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupArrayToArrayBogusTarget() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", Principal[].class, Integer[].class); + service.getConversionExecutor("princy", type(Principal[].class), type(Integer[].class)); } catch (ConversionExecutorNotFoundException e) { } @@ -380,7 +398,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionArrayToCollection() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", String[].class, List.class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(String[].class), type(List.class)); List list = (List) executor.execute(new String[] { "princy1", "princy2" }); assertEquals("princy1", ((Principal) list.get(0)).getName()); assertEquals("princy2", ((Principal) list.get(1)).getName()); @@ -388,7 +406,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionArrayToCollectionReverse() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", Principal[].class, List.class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(Principal[].class), type(List.class)); final Principal princy1 = new Principal() { public String getName() { return "princy1"; @@ -407,7 +425,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupArrayToCollectionBogusSource() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", Integer[].class, List.class); + service.getConversionExecutor("princy", type(Integer[].class), type(List.class)); fail("Should have failed"); } catch (ConversionExecutorNotFoundException e) { @@ -416,7 +434,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupCollectionToArray() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", List.class, Principal[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(List.class), type(Principal[].class)); List princyList = new ArrayList(); princyList.add("princy1"); princyList.add("princy2"); @@ -427,7 +445,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupCollectionToArrayReverse() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", List.class, String[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(List.class), type(String[].class)); final Principal princy1 = new Principal() { public String getName() { return "princy1"; @@ -449,7 +467,7 @@ public class GenericConversionServiceTests extends TestCase { public void testtestCustomConverterLookupCollectionToArrayBogusTarget() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", List.class, Integer[].class); + service.getConversionExecutor("princy", type(List.class), type(Integer[].class)); fail("Should have failed"); } catch (ConversionExecutorNotFoundException e) { @@ -458,14 +476,14 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterConversionObjectToArray() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", String.class, Principal[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(String.class), type(Principal[].class)); Principal[] p = (Principal[]) executor.execute("princy1"); assertEquals("princy1", p[0].getName()); } public void testCustomConverterConversionObjectToArrayReverse() { service.addConverter("princy", new CustomTwoWayConverter()); - ConversionExecutor executor = service.getConversionExecutor("princy", Principal.class, String[].class); + ConversionExecutor executor = service.getConversionExecutor("princy", type(Principal.class), type(String[].class)); final Principal princy1 = new Principal() { public String getName() { return "princy1"; @@ -478,7 +496,7 @@ public class GenericConversionServiceTests extends TestCase { public void testCustomConverterLookupObjectToArrayBogusSource() { service.addConverter("princy", new CustomTwoWayConverter()); try { - service.getConversionExecutor("princy", Integer.class, Principal[].class); + service.getConversionExecutor("princy", type(Integer.class), type(Principal[].class)); fail("Should have failed"); } catch (ConversionExecutorNotFoundException e) {