spring build 582

This commit is contained in:
Keith Donald
2009-02-13 13:57:52 +00:00
parent b20397e4d2
commit ce6fdc9da9
6 changed files with 155 additions and 27 deletions

View File

@@ -31,6 +31,8 @@ public class ArrayToArray implements Converter {
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
@@ -39,6 +41,10 @@ public class ArrayToArray implements Converter {
this.conversionService = conversionService;
}
public ArrayToArray(ConversionExecutor elementConverter) {
this.elementConverter = elementConverter;
}
public Class getSourceClass() {
return Object[].class;
}
@@ -55,12 +61,19 @@ public class ArrayToArray implements Converter {
Class targetComponentType = targetClass.getComponentType();
int length = Array.getLength(source);
Object targetArray = Array.newInstance(targetComponentType, length);
ConversionExecutor converter = conversionService
.getConversionExecutor(sourceComponentType, targetComponentType);
ConversionExecutor converter = getElementConverter(sourceComponentType, targetComponentType);
for (int i = 0; i < length; i++) {
Object value = Array.get(source, i);
Array.set(targetArray, i, converter.execute(value));
}
return targetArray;
}
private ConversionExecutor getElementConverter(Class sourceComponentType, Class targetComponentType) {
if (elementConverter != null) {
return elementConverter;
} else {
return conversionService.getConversionExecutor(sourceComponentType, targetComponentType);
}
}
}

View File

@@ -32,7 +32,7 @@ import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.JdkVersion;
/**
* Special one-way converter that converts from a source array to a target collection. Supports the selection of an
* Special converter that converts from a source array to a target collection. Supports the selection of an
* "approximate" collection implementation when a target collection interface such as <code>List.class</code> is
* specified. Supports type conversion of array elements when a concrete parameterized collection class is provided,
* such as <code>IntegerList<Integer>.class</code>.
@@ -48,10 +48,16 @@ public class ArrayToCollection implements TwoWayConverter {
private ConversionService conversionService;
private ConversionExecutor elementConverter;
public ArrayToCollection(ConversionService conversionService) {
this.conversionService = conversionService;
}
public ArrayToCollection(ConversionExecutor elementConverter) {
this.elementConverter = elementConverter;
}
public Class getSourceClass() {
return Object[].class;
}
@@ -67,7 +73,7 @@ public class ArrayToCollection implements TwoWayConverter {
Class collectionImplClass = getCollectionImplClass(targetClass);
Constructor constructor = collectionImplClass.getConstructor(null);
Collection collection = (Collection) constructor.newInstance(null);
ConversionExecutor converter = getElementConverter(source, targetClass);
ConversionExecutor converter = getArrayElementConverter(source, targetClass);
int length = Array.getLength(source);
for (int i = 0; i < length; i++) {
Object value = Array.get(source, i);
@@ -114,15 +120,19 @@ public class ArrayToCollection implements TwoWayConverter {
}
}
private ConversionExecutor getElementConverter(Object source, Class targetClass) {
if (JdkVersion.isAtLeastJava15()) {
Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass);
if (elementType != null) {
Class componentType = source.getClass().getComponentType();
return conversionService.getConversionExecutor(componentType, elementType);
private ConversionExecutor getArrayElementConverter(Object source, Class targetClass) {
if (elementConverter != null) {
return elementConverter;
} else {
if (JdkVersion.isAtLeastJava15()) {
Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass);
if (elementType != null) {
Class componentType = source.getClass().getComponentType();
return conversionService.getConversionExecutor(componentType, elementType);
}
}
return null;
}
return null;
}
}

View File

@@ -20,6 +20,7 @@ import java.math.BigInteger;
import java.util.Date;
import java.util.Locale;
import org.springframework.binding.convert.converters.CollectionToCollection;
import org.springframework.binding.convert.converters.NumberToNumber;
import org.springframework.binding.convert.converters.ObjectToCollection;
import org.springframework.binding.convert.converters.StringToBigDecimal;
@@ -72,8 +73,9 @@ public class DefaultConversionService extends GenericConversionService {
addConverter(new StringToLocale());
addConverter(new StringToDate());
addConverter(new StringToLabeledEnum());
addConverter(new ObjectToCollection(this));
addConverter(new NumberToNumber());
addConverter(new ObjectToCollection(this));
addConverter(new CollectionToCollection(this));
if (ClassUtils.isPresent("java.lang.Enum", this.getClass().getClassLoader())) {
addConverter(new StringToEnum());
}

View File

@@ -130,6 +130,7 @@ public class GenericConversionService implements ConversionService {
if (targetClass.isAssignableFrom(sourceClass)) {
return new StaticConversionExecutor(sourceClass, targetClass, new NoOpConverter(sourceClass, targetClass));
}
// special handling for arrays since they are not indexable classes
if (sourceClass.isArray()) {
if (targetClass.isArray()) {
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToArray(this));
@@ -183,6 +184,66 @@ public class GenericConversionService implements ConversionService {
}
sourceClass = convertToWrapperClassIfNecessary(sourceClass);
targetClass = convertToWrapperClassIfNecessary(targetClass);
if (sourceClass.isArray()) {
Class sourceComponentType = sourceClass.getComponentType();
if (targetClass.isArray()) {
Class targetComponentType = targetClass.getComponentType();
if (converter.getSourceClass().isAssignableFrom(sourceComponentType)) {
if (!converter.getTargetClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to an array of type [" + targetComponentType + "]");
}
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, converter);
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToArray(elementConverter));
} else if (converter.getTargetClass().isAssignableFrom(sourceComponentType)
&& converter instanceof TwoWayConverter) {
TwoWayConverter twoWay = (TwoWayConverter) converter;
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, new ReverseConverter(twoWay));
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToArray(elementConverter));
} else {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to an array of type [" + targetComponentType + "]");
}
} else if (Collection.class.isAssignableFrom(targetClass)) {
// type erasure has prevented us from getting the concrete type, this is best we can do for now
Class targetComponentType = converter.getTargetClass();
if (converter.getSourceClass().isAssignableFrom(sourceComponentType)) {
if (!converter.getTargetClass().isAssignableFrom(targetComponentType)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to collection of type [" + targetComponentType
+ "]");
}
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, converter);
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToCollection(
elementConverter));
} else if (converter.getTargetClass().isAssignableFrom(sourceComponentType)
&& converter instanceof TwoWayConverter) {
TwoWayConverter twoWay = (TwoWayConverter) converter;
ConversionExecutor elementConverter = new StaticConversionExecutor(sourceComponentType,
targetComponentType, new ReverseConverter(twoWay));
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToCollection(
elementConverter));
} else {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
"Custom ConversionExecutor with id '" + id + "' cannot convert from array of type ["
+ sourceComponentType + "]; to collection of type [" + targetComponentType + "]");
}
}
}
if (targetClass.isArray()) {
if (Collection.class.isAssignableFrom(sourceClass)) {
// type erasure limits us here as well
throw new UnsupportedOperationException("Not yet implemented");
} else {
throw new UnsupportedOperationException("Not yet implemented");
}
}
if (converter.getSourceClass().isAssignableFrom(sourceClass)) {
if (!converter.getTargetClass().isAssignableFrom(targetClass)) {
throw new ConversionExecutorNotFoundException(sourceClass, targetClass,