From 7f6fc4e82edd17c32aa7a17587da471ab64a23d6 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Tue, 31 Mar 2009 15:44:25 +0000 Subject: [PATCH] polish --- .../convert/ConversionExecutionException.java | 6 +-- .../core/convert/ConversionExecutor.java | 2 +- .../ConversionExecutorNotFoundException.java | 5 +- .../core/convert/ConversionService.java | 8 +-- .../core/convert/TypeDescriptor.java | 2 +- .../core/convert/TypedValue.java | 2 + .../service/DefaultConversionService.java | 2 +- .../service/GenericConversionService.java | 51 +++++++++---------- .../service/StaticConversionExecutor.java | 15 ++---- .../StaticSuperConversionExecutor.java | 2 +- .../SuperTwoWayConverterConverter.java | 29 +++++++---- .../GenericConversionServiceTests.java | 5 +- 12 files changed, 66 insertions(+), 63 deletions(-) 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 a377cb40c6..862664f32b 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 @@ -68,7 +68,7 @@ public class ConversionExecutionException extends ConversionException { } /** - * Returns the actual value we tried to convert, an instance of {@link #getSourceClass()}. + * Returns the actual value we tried to convert, an instance of {@link #getSourceType()}. */ public Object getValue() { return value; @@ -77,14 +77,14 @@ public class ConversionExecutionException extends ConversionException { /** * Returns the source type we tried to convert the value from. */ - public TypeDescriptor getSourceClass() { + public TypeDescriptor getSourceType() { return sourceType; } /** * Returns the target type we tried to convert the value to. */ - public TypeDescriptor getTargetClass() { + public TypeDescriptor getTargetType() { return targetType; } 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 ff7da4481f..3059f003b7 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 @@ -25,7 +25,7 @@ package org.springframework.core.convert; public interface ConversionExecutor { /** - * Convert the source to T. + * Convert the source. * @param source the source to convert * @throws ConversionExecutionException if an exception occurs during type conversion */ 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 6b743bc2dc..abf4badb6b 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 @@ -18,7 +18,6 @@ package org.springframework.core.convert; /** * Thrown when a conversion executor could not be found in a conversion service. * - * @see ConversionService#getConversionExecutor(Class, Class) * @author Keith Donald */ public class ConversionExecutorNotFoundException extends ConversionException { @@ -40,14 +39,14 @@ public class ConversionExecutorNotFoundException extends ConversionException { } /** - * Returns the source type requested to convert from. + * Returns the source type that was requested to convert from. */ public TypeDescriptor getSourceType() { return sourceType; } /** - * Returns the target type requested to convert to. + * Returns the target type that was requested to convert to. */ 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 5f3edc83cc..a7966e8932 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 @@ -17,10 +17,12 @@ package org.springframework.core.convert; /** * A service interface for type conversion. This is the entry point into the convert system. Call one of the - * {@link #executeConversion(Object, Class) executeConversion} operations to perform a thread-safe type conversion using - * this system. Call one of the {@link #getConversionExecutor(Class, Class) getConversionExecutor} operations to obtain + * executeConversion operations to perform a thread-safe type conversion using + * this system. Call one of the getConversionExecutor operations to obtain * a thread-safe {@link ConversionExecutor} command for later use. * + * TODO - is TypeDescriptor/TypedValue needed on source? + * * @author Keith Donald */ public interface ConversionService { @@ -86,7 +88,7 @@ public interface ConversionService { TypeDescriptor targetType) throws ConversionExecutorNotFoundException; /** - * Get a type by its name; may be the fully-qualified class name or a registered alias. + * Get a type by its name; may be the fully-qualified class name or a registered type alias such as 'int'. * @return the class, or null if no such name exists */ public Class getType(String name); 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 index a8cedc6b27..7cadb734c7 100644 --- 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 @@ -10,7 +10,7 @@ import org.springframework.core.MethodParameter; import org.springframework.util.Assert; /** - * Type metadata about a bindable value. + * Type metadata about a bindable target value. * * @author Keith Donald */ 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 index 4a0ace1ba2..3ca258c9c4 100644 --- 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 @@ -7,6 +7,8 @@ package org.springframework.core.convert; * It also allows access to field-level or method-level annotations. * All of this context can be utilized when performing a type conversion as part of a data binding routine. * + * TODO - is this needed? + * * @author Keith Donald */ public class TypedValue { 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 07326f722a..4533f41ab5 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 @@ -79,7 +79,7 @@ public class DefaultConversionService extends GenericConversionService { addAlias("long", Long.class); addAlias("float", Float.class); addAlias("double", Double.class); - addAlias("bigInteger", BigInteger.class); + addAlias("bigInt", BigInteger.class); addAlias("bigDecimal", BigDecimal.class); addAlias("locale", Locale.class); addAlias("enum", Enum.class); 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 696b53add4..1ac6d14b6f 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 @@ -15,12 +15,10 @@ */ package org.springframework.core.convert.service; -import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; @@ -35,6 +33,7 @@ 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.ConverterInfo; import org.springframework.core.convert.converter.SuperConverter; import org.springframework.core.convert.converter.SuperTwoWayConverter; import org.springframework.util.Assert; @@ -42,8 +41,6 @@ import org.springframework.util.Assert; /** * Base implementation of a conversion service. Initially empty, e.g. no converters are registered by default. * - * TODO auto-conversion of generic collection elements - * * @author Keith Donald */ @SuppressWarnings("unchecked") @@ -137,9 +134,6 @@ public class GenericConversionService implements ConversionService { /** * Adapts a {@link SuperTwoWayConverter} that converts between BS and BT class hierarchies to a {@link Converter} * that converts between the specific BS/BT sub types S and T. - * - * TODO - I think this is going to force indexing on a getSourceClass/getTargetclass prop instead generic args - * * @param sourceClass the source class S to convert from, which must be equal or extend BS * @param targetClass the target type T to convert to, which must equal or extend BT * @param converter the super two way converter @@ -147,12 +141,12 @@ public class GenericConversionService implements ConversionService { */ public static Converter converterFor(Class sourceClass, Class targetClass, SuperTwoWayConverter converter) { - return new SuperTwoWayConverterConverter(converter, sourceClass, targetClass); + return new SuperTwoWayConverterConverter(converter, sourceClass, targetClass); } /** - * Add a convenient alias for the target type. {@link #getType(String)} can then be used to lookup the type - * given the alias. + * Add a convenient alias for the target type. {@link #getType(String)} can then be used to lookup the type given + * the alias. * @see #getType(String) */ public void addAlias(String alias, Class targetType) { @@ -164,9 +158,9 @@ public class GenericConversionService implements ConversionService { public boolean canConvert(TypedValue source, TypeDescriptor targetType) { return false; } - - public Object executeConversion(TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, - ConversionException { + + public Object executeConversion(TypedValue source, TypeDescriptor targetType) + throws ConversionExecutorNotFoundException, ConversionException { Assert.notNull(source, "The source to convert from is required"); if (source.isNull()) { return null; @@ -179,7 +173,7 @@ public class GenericConversionService implements ConversionService { Assert.notNull(source, "The source to convert from is required"); if (source.isNull()) { return null; - } + } return getConversionExecutor(converterId, source.getTypeDescriptor(), targetType).execute(source.getValue()); } @@ -204,14 +198,14 @@ public class GenericConversionService implements ConversionService { if (sourceType.isCollection()) { return new CollectionToArray(sourceType, targetType, this); } else { - throw new UnsupportedOperationException("Object to Array not yet supported"); + throw new UnsupportedOperationException("Object to Array conversion not yet supported"); } } if (sourceType.isCollection()) { if (targetType.isCollection()) { return new CollectionToCollection(sourceType, targetType, this); } else { - throw new UnsupportedOperationException("Object to collection not yet supported"); + throw new UnsupportedOperationException("Object to Collection conversion not yet supported"); } } Converter converter = findRegisteredConverter(sourceType, targetType); @@ -257,18 +251,22 @@ public class GenericConversionService implements ConversionService { private List getRequiredTypeInfo(Object converter) { List typeInfo = new ArrayList(2); + if (converter instanceof ConverterInfo) { + ConverterInfo info = (ConverterInfo) converter; + typeInfo.add(info.getSourceType()); + typeInfo.add(info.getTargetType()); + return typeInfo; + } Class classToIntrospect = converter.getClass(); while (classToIntrospect != null) { Type[] genericInterfaces = classToIntrospect.getGenericInterfaces(); for (Type genericInterface : genericInterfaces) { if (genericInterface instanceof ParameterizedType) { - ParameterizedType parameterizedInterface = (ParameterizedType) genericInterface; - if (Converter.class.equals(parameterizedInterface.getRawType()) - || SuperConverter.class.isAssignableFrom((Class) parameterizedInterface.getRawType())) { - Class s = getParameterClass(parameterizedInterface.getActualTypeArguments()[0], converter - .getClass()); - Class t = getParameterClass(parameterizedInterface.getActualTypeArguments()[1], converter - .getClass()); + ParameterizedType pInterface = (ParameterizedType) genericInterface; + if (Converter.class.equals(pInterface.getRawType()) + || SuperConverter.class.isAssignableFrom((Class) pInterface.getRawType())) { + Class s = getParameterClass(pInterface.getActualTypeArguments()[0], converter.getClass()); + Class t = getParameterClass(pInterface.getActualTypeArguments()[1], converter.getClass()); typeInfo.add(getParameterClass(s, converter.getClass())); typeInfo.add(getParameterClass(t, converter.getClass())); break; @@ -315,7 +313,7 @@ public class GenericConversionService implements ConversionService { private Converter findRegisteredConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { Class sourceClass = sourceType.getWrapperTypeIfPrimitive(); - Class targetClass = targetType.getWrapperTypeIfPrimitive(); + Class targetClass = targetType.getWrapperTypeIfPrimitive(); if (sourceClass.isInterface()) { LinkedList classQueue = new LinkedList(); classQueue.addFirst(sourceClass); @@ -366,7 +364,7 @@ public class GenericConversionService implements ConversionService { private SuperConverter findRegisteredSuperConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { Class sourceClass = sourceType.getWrapperTypeIfPrimitive(); - Class targetClass = targetType.getWrapperTypeIfPrimitive(); + Class targetClass = targetType.getWrapperTypeIfPrimitive(); if (sourceClass.isInterface()) { LinkedList classQueue = new LinkedList(); classQueue.addFirst(sourceClass); @@ -452,7 +450,8 @@ public class GenericConversionService implements ConversionService { } public ConversionExecutor getElementConverter(Class sourceElementType, Class targetElementType) { - return getConversionExecutor(TypeDescriptor.valueOf(sourceElementType), TypeDescriptor.valueOf(targetElementType)); + return getConversionExecutor(TypeDescriptor.valueOf(sourceElementType), TypeDescriptor + .valueOf(targetElementType)); } } \ 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 b48203f7ca..9c53bde825 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 @@ -21,6 +21,7 @@ import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.style.ToStringCreator; +@SuppressWarnings("unchecked") class StaticConversionExecutor implements ConversionExecutor { private final TypeDescriptor sourceType; @@ -35,26 +36,18 @@ class StaticConversionExecutor implements ConversionExecutor { this.converter = converter; } - public TypeDescriptor getSourceType() { - return sourceType; - } - - public TypeDescriptor getTargetType() { - return targetType; - } - public Object execute(Object source) throws ConversionExecutionException { if (source == null) { return null; } 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() + "]"); + 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); } catch (Exception e) { - throw new ConversionExecutionException(source, getSourceType(), getTargetType(), e); + throw new ConversionExecutionException(source, sourceType, targetType, e); } } 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 bf8c17c3aa..42da8f31f4 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 @@ -20,8 +20,8 @@ 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; +@SuppressWarnings("unchecked") class StaticSuperConversionExecutor implements ConversionExecutor { private final TypeDescriptor sourceType; diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java index 7bf4091db9..ac1de0b4ba 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java @@ -1,6 +1,7 @@ package org.springframework.core.convert.service; import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.ConverterInfo; import org.springframework.core.convert.converter.SuperConverter; import org.springframework.core.convert.converter.SuperTwoWayConverter; @@ -9,26 +10,34 @@ import org.springframework.core.convert.converter.SuperTwoWayConverter; * for applying more general {@link SuperConverter} logic to a specific source/target class pair. */ @SuppressWarnings("unchecked") -class SuperTwoWayConverterConverter implements Converter { +class SuperTwoWayConverterConverter implements Converter, ConverterInfo { private SuperTwoWayConverter superConverter; - private Class sourceClass; + private Class sourceType; - private Class targetClass; + private Class targetType; - public SuperTwoWayConverterConverter(SuperTwoWayConverter superConverter, Class sourceClass, Class targetClass) { + public SuperTwoWayConverterConverter(SuperTwoWayConverter superConverter, Class sourceType, Class targetType) { this.superConverter = superConverter; - this.sourceClass = sourceClass; - this.targetClass = targetClass; + this.sourceType = sourceType; + this.targetType = targetType; + } + + public Class getSourceType() { + return sourceType; + } + + public Class getTargetType() { + return targetType; } - public T convert(S source) throws Exception { - return (T) superConverter.convert(source, targetClass); + public Object convert(Object source) throws Exception { + return superConverter.convert(source, targetType); } - public S convertBack(T target) throws Exception { - return (S) superConverter.convertBack(target, sourceClass); + public Object convertBack(Object target) throws Exception { + return superConverter.convertBack(target, sourceType); } } 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 5e21ec7799..80ab88e9fd 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 @@ -575,9 +575,8 @@ public class GenericConversionServiceTests extends TestCase { } public void testSuperTwoWayConverterConverterAdaption() { - // this fails at the moment - //service.addConverter(GenericConversionService.converterFor(String.class, FooEnum.class, new StringToEnum())); - //assertEquals(FooEnum.BAR, service.executeConversion("BAR", FooEnum.class)); + service.addConverter(GenericConversionService.converterFor(String.class, FooEnum.class, new StringToEnum())); + assertEquals(FooEnum.BAR, service.executeConversion(value("BAR"), type(FooEnum.class))); } private TypedValue value(Object obj) {