spring build 582
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user