Browse Source

polish

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@890 50f2f4bb-b051-0410-bef5-90022cba6387
pull/1/head
Keith Donald 17 years ago
parent
commit
b44928bbbc
  1. 6
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutionException.java
  2. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java
  3. 5
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutorNotFoundException.java
  4. 8
      org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.java
  5. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
  6. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/TypedValue.java
  7. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/service/DefaultConversionService.java
  8. 51
      org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java
  9. 15
      org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticConversionExecutor.java
  10. 2
      org.springframework.core/src/main/java/org/springframework/core/convert/service/StaticSuperConversionExecutor.java
  11. 29
      org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java
  12. 5
      org.springframework.core/src/test/java/org/springframework/core/convert/service/GenericConversionServiceTests.java

6
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() { public Object getValue() {
return value; return value;
@ -77,14 +77,14 @@ public class ConversionExecutionException extends ConversionException {
/** /**
* Returns the source type we tried to convert the value from. * Returns the source type we tried to convert the value from.
*/ */
public TypeDescriptor getSourceClass() { public TypeDescriptor getSourceType() {
return sourceType; return sourceType;
} }
/** /**
* Returns the target type we tried to convert the value to. * Returns the target type we tried to convert the value to.
*/ */
public TypeDescriptor getTargetClass() { public TypeDescriptor getTargetType() {
return targetType; return targetType;
} }

2
org.springframework.core/src/main/java/org/springframework/core/convert/ConversionExecutor.java

@ -25,7 +25,7 @@ package org.springframework.core.convert;
public interface ConversionExecutor { public interface ConversionExecutor {
/** /**
* Convert the source to T. * Convert the source.
* @param source the source to convert * @param source the source to convert
* @throws ConversionExecutionException if an exception occurs during type conversion * @throws ConversionExecutionException if an exception occurs during type conversion
*/ */

5
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. * Thrown when a conversion executor could not be found in a conversion service.
* *
* @see ConversionService#getConversionExecutor(Class, Class)
* @author Keith Donald * @author Keith Donald
*/ */
public class ConversionExecutorNotFoundException extends ConversionException { 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() { public TypeDescriptor getSourceType() {
return sourceType; return sourceType;
} }
/** /**
* Returns the target type requested to convert to. * Returns the target type that was requested to convert to.
*/ */
public TypeDescriptor getTargetType() { public TypeDescriptor getTargetType() {
return targetType; return targetType;

8
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 * 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 * <i>executeConversion</i> operations to perform a thread-safe type conversion using
* this system. Call one of the {@link #getConversionExecutor(Class, Class) getConversionExecutor} operations to obtain * this system. Call one of the <i>getConversionExecutor</i> operations to obtain
* a thread-safe {@link ConversionExecutor} command for later use. * a thread-safe {@link ConversionExecutor} command for later use.
* *
* TODO - is TypeDescriptor/TypedValue needed on source?
*
* @author Keith Donald * @author Keith Donald
*/ */
public interface ConversionService { public interface ConversionService {
@ -86,7 +88,7 @@ public interface ConversionService {
TypeDescriptor targetType) throws ConversionExecutorNotFoundException; 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 <code>null</code> if no such name exists * @return the class, or <code>null</code> if no such name exists
*/ */
public Class<?> getType(String name); public Class<?> getType(String name);

2
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; import org.springframework.util.Assert;
/** /**
* Type metadata about a bindable value. * Type metadata about a bindable target value.
* *
* @author Keith Donald * @author Keith Donald
*/ */

2
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. * 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. * 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 * @author Keith Donald
*/ */
public class TypedValue { public class TypedValue {

2
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("long", Long.class);
addAlias("float", Float.class); addAlias("float", Float.class);
addAlias("double", Double.class); addAlias("double", Double.class);
addAlias("bigInteger", BigInteger.class); addAlias("bigInt", BigInteger.class);
addAlias("bigDecimal", BigDecimal.class); addAlias("bigDecimal", BigDecimal.class);
addAlias("locale", Locale.class); addAlias("locale", Locale.class);
addAlias("enum", Enum.class); addAlias("enum", Enum.class);

51
org.springframework.core/src/main/java/org/springframework/core/convert/service/GenericConversionService.java

@ -15,12 +15,10 @@
*/ */
package org.springframework.core.convert.service; package org.springframework.core.convert.service;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; 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.TypeDescriptor;
import org.springframework.core.convert.TypedValue; import org.springframework.core.convert.TypedValue;
import org.springframework.core.convert.converter.Converter; 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.SuperConverter;
import org.springframework.core.convert.converter.SuperTwoWayConverter; import org.springframework.core.convert.converter.SuperTwoWayConverter;
import org.springframework.util.Assert; 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. * 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 * @author Keith Donald
*/ */
@SuppressWarnings("unchecked") @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} * 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. * 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 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 targetClass the target type T to convert to, which must equal or extend BT
* @param converter the super two way converter * @param converter the super two way converter
@ -147,12 +141,12 @@ public class GenericConversionService implements ConversionService {
*/ */
public static <S, T> Converter<S, T> converterFor(Class<S> sourceClass, Class<T> targetClass, public static <S, T> Converter<S, T> converterFor(Class<S> sourceClass, Class<T> targetClass,
SuperTwoWayConverter converter) { SuperTwoWayConverter converter) {
return new SuperTwoWayConverterConverter<S, T>(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 * Add a convenient alias for the target type. {@link #getType(String)} can then be used to lookup the type given
* given the alias. * the alias.
* @see #getType(String) * @see #getType(String)
*/ */
public void addAlias(String alias, Class targetType) { public void addAlias(String alias, Class targetType) {
@ -164,9 +158,9 @@ public class GenericConversionService implements ConversionService {
public boolean canConvert(TypedValue source, TypeDescriptor targetType) { public boolean canConvert(TypedValue source, TypeDescriptor targetType) {
return false; return false;
} }
public Object executeConversion(TypedValue source, TypeDescriptor targetType) throws ConversionExecutorNotFoundException, public Object executeConversion(TypedValue source, TypeDescriptor targetType)
ConversionException { throws ConversionExecutorNotFoundException, ConversionException {
Assert.notNull(source, "The source to convert from is required"); Assert.notNull(source, "The source to convert from is required");
if (source.isNull()) { if (source.isNull()) {
return null; return null;
@ -179,7 +173,7 @@ public class GenericConversionService implements ConversionService {
Assert.notNull(source, "The source to convert from is required"); Assert.notNull(source, "The source to convert from is required");
if (source.isNull()) { if (source.isNull()) {
return null; return null;
} }
return getConversionExecutor(converterId, source.getTypeDescriptor(), targetType).execute(source.getValue()); return getConversionExecutor(converterId, source.getTypeDescriptor(), targetType).execute(source.getValue());
} }
@ -204,14 +198,14 @@ public class GenericConversionService implements ConversionService {
if (sourceType.isCollection()) { if (sourceType.isCollection()) {
return new CollectionToArray(sourceType, targetType, this); return new CollectionToArray(sourceType, targetType, this);
} else { } else {
throw new UnsupportedOperationException("Object to Array not yet supported"); throw new UnsupportedOperationException("Object to Array conversion not yet supported");
} }
} }
if (sourceType.isCollection()) { if (sourceType.isCollection()) {
if (targetType.isCollection()) { if (targetType.isCollection()) {
return new CollectionToCollection(sourceType, targetType, this); return new CollectionToCollection(sourceType, targetType, this);
} else { } 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); Converter converter = findRegisteredConverter(sourceType, targetType);
@ -257,18 +251,22 @@ public class GenericConversionService implements ConversionService {
private List getRequiredTypeInfo(Object converter) { private List getRequiredTypeInfo(Object converter) {
List typeInfo = new ArrayList(2); 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(); Class classToIntrospect = converter.getClass();
while (classToIntrospect != null) { while (classToIntrospect != null) {
Type[] genericInterfaces = classToIntrospect.getGenericInterfaces(); Type[] genericInterfaces = classToIntrospect.getGenericInterfaces();
for (Type genericInterface : genericInterfaces) { for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) { if (genericInterface instanceof ParameterizedType) {
ParameterizedType parameterizedInterface = (ParameterizedType) genericInterface; ParameterizedType pInterface = (ParameterizedType) genericInterface;
if (Converter.class.equals(parameterizedInterface.getRawType()) if (Converter.class.equals(pInterface.getRawType())
|| SuperConverter.class.isAssignableFrom((Class) parameterizedInterface.getRawType())) { || SuperConverter.class.isAssignableFrom((Class) pInterface.getRawType())) {
Class s = getParameterClass(parameterizedInterface.getActualTypeArguments()[0], converter Class s = getParameterClass(pInterface.getActualTypeArguments()[0], converter.getClass());
.getClass()); Class t = getParameterClass(pInterface.getActualTypeArguments()[1], converter.getClass());
Class t = getParameterClass(parameterizedInterface.getActualTypeArguments()[1], converter
.getClass());
typeInfo.add(getParameterClass(s, converter.getClass())); typeInfo.add(getParameterClass(s, converter.getClass()));
typeInfo.add(getParameterClass(t, converter.getClass())); typeInfo.add(getParameterClass(t, converter.getClass()));
break; break;
@ -315,7 +313,7 @@ public class GenericConversionService implements ConversionService {
private Converter findRegisteredConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { private Converter findRegisteredConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> sourceClass = sourceType.getWrapperTypeIfPrimitive(); Class<?> sourceClass = sourceType.getWrapperTypeIfPrimitive();
Class<?> targetClass = targetType.getWrapperTypeIfPrimitive(); Class<?> targetClass = targetType.getWrapperTypeIfPrimitive();
if (sourceClass.isInterface()) { if (sourceClass.isInterface()) {
LinkedList classQueue = new LinkedList(); LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass); classQueue.addFirst(sourceClass);
@ -366,7 +364,7 @@ public class GenericConversionService implements ConversionService {
private SuperConverter findRegisteredSuperConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { private SuperConverter findRegisteredSuperConverter(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> sourceClass = sourceType.getWrapperTypeIfPrimitive(); Class<?> sourceClass = sourceType.getWrapperTypeIfPrimitive();
Class<?> targetClass = targetType.getWrapperTypeIfPrimitive(); Class<?> targetClass = targetType.getWrapperTypeIfPrimitive();
if (sourceClass.isInterface()) { if (sourceClass.isInterface()) {
LinkedList classQueue = new LinkedList(); LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass); classQueue.addFirst(sourceClass);
@ -452,7 +450,8 @@ public class GenericConversionService implements ConversionService {
} }
public ConversionExecutor getElementConverter(Class<?> sourceElementType, Class<?> targetElementType) { public ConversionExecutor getElementConverter(Class<?> sourceElementType, Class<?> targetElementType) {
return getConversionExecutor(TypeDescriptor.valueOf(sourceElementType), TypeDescriptor.valueOf(targetElementType)); return getConversionExecutor(TypeDescriptor.valueOf(sourceElementType), TypeDescriptor
.valueOf(targetElementType));
} }
} }

15
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.convert.converter.Converter;
import org.springframework.core.style.ToStringCreator; import org.springframework.core.style.ToStringCreator;
@SuppressWarnings("unchecked")
class StaticConversionExecutor implements ConversionExecutor { class StaticConversionExecutor implements ConversionExecutor {
private final TypeDescriptor sourceType; private final TypeDescriptor sourceType;
@ -35,26 +36,18 @@ class StaticConversionExecutor implements ConversionExecutor {
this.converter = converter; this.converter = converter;
} }
public TypeDescriptor getSourceType() {
return sourceType;
}
public TypeDescriptor getTargetType() {
return targetType;
}
public Object execute(Object source) throws ConversionExecutionException { public Object execute(Object source) throws ConversionExecutionException {
if (source == null) { if (source == null) {
return null; return null;
} }
if (sourceType != null && !sourceType.isInstance(source)) { if (sourceType != null && !sourceType.isInstance(source)) {
throw new ConversionExecutionException(source, getSourceType(), getTargetType(), "Source object " throw new ConversionExecutionException(source, sourceType, targetType, "Source object "
+ source + " to convert is expected to be an instance of [" + getSourceType().getName() + "]"); + source + " to convert is expected to be an instance of [" + sourceType.getName() + "]");
} }
try { try {
return converter.convert(source); return converter.convert(source);
} catch (Exception e) { } catch (Exception e) {
throw new ConversionExecutionException(source, getSourceType(), getTargetType(), e); throw new ConversionExecutionException(source, sourceType, targetType, e);
} }
} }

2
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.TypeDescriptor;
import org.springframework.core.convert.converter.SuperConverter; import org.springframework.core.convert.converter.SuperConverter;
import org.springframework.core.style.ToStringCreator; import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
@SuppressWarnings("unchecked")
class StaticSuperConversionExecutor implements ConversionExecutor { class StaticSuperConversionExecutor implements ConversionExecutor {
private final TypeDescriptor sourceType; private final TypeDescriptor sourceType;

29
org.springframework.core/src/main/java/org/springframework/core/convert/service/SuperTwoWayConverterConverter.java

@ -1,6 +1,7 @@
package org.springframework.core.convert.service; package org.springframework.core.convert.service;
import org.springframework.core.convert.converter.Converter; 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.SuperConverter;
import org.springframework.core.convert.converter.SuperTwoWayConverter; 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. * for applying more general {@link SuperConverter} logic to a specific source/target class pair.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
class SuperTwoWayConverterConverter<S, T> implements Converter<S, T> { class SuperTwoWayConverterConverter implements Converter, ConverterInfo {
private SuperTwoWayConverter superConverter; 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.superConverter = superConverter;
this.sourceClass = sourceClass; this.sourceType = sourceType;
this.targetClass = targetClass; this.targetType = targetType;
}
public Class getSourceType() {
return sourceType;
}
public Class getTargetType() {
return targetType;
} }
public T convert(S source) throws Exception { public Object convert(Object source) throws Exception {
return (T) superConverter.convert(source, targetClass); return superConverter.convert(source, targetType);
} }
public S convertBack(T target) throws Exception { public Object convertBack(Object target) throws Exception {
return (S) superConverter.convertBack(target, sourceClass); return superConverter.convertBack(target, sourceType);
} }
} }

5
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() { public void testSuperTwoWayConverterConverterAdaption() {
// this fails at the moment service.addConverter(GenericConversionService.converterFor(String.class, FooEnum.class, new StringToEnum()));
//service.addConverter(GenericConversionService.converterFor(String.class, FooEnum.class, new StringToEnum())); assertEquals(FooEnum.BAR, service.executeConversion(value("BAR"), type(FooEnum.class)));
//assertEquals(FooEnum.BAR, service.executeConversion("BAR", FooEnum.class));
} }
private TypedValue value(Object obj) { private TypedValue value(Object obj) {

Loading…
Cancel
Save