fixed collection element conversion using ConversionService (SPR-6950)
This commit is contained in:
@@ -196,8 +196,9 @@ class TypeConverterDelegate {
|
||||
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
|
||||
if (editor == null && conversionService != null && convertedValue != null) {
|
||||
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(convertedValue);
|
||||
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
|
||||
return (T) conversionService.convert(convertedValue, sourceTypeDesc, typeDescriptor);
|
||||
TypeDescriptor targetTypeDesc = typeDescriptor.forElementType(requiredType);
|
||||
if (conversionService.canConvert(sourceTypeDesc, targetTypeDesc)) {
|
||||
return (T) conversionService.convert(convertedValue, sourceTypeDesc, targetTypeDesc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +206,8 @@ class TypeConverterDelegate {
|
||||
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
|
||||
if (requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
|
||||
convertedValue instanceof String && typeDescriptor.getMethodParameter() != null) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(typeDescriptor.getMethodParameter());
|
||||
if (elementType != null && Enum.class.isAssignableFrom(elementType)) {
|
||||
Class elemType = GenericCollectionTypeResolver.getCollectionParameterType(typeDescriptor.getMethodParameter());
|
||||
if (elemType != null && Enum.class.isAssignableFrom(elemType)) {
|
||||
convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
|
||||
}
|
||||
}
|
||||
@@ -572,7 +573,8 @@ class TypeConverterDelegate {
|
||||
if (methodParam != null) {
|
||||
methodParam.increaseNestingLevel();
|
||||
}
|
||||
Object convertedElement = convertIfNecessary(indexedPropertyName, null, element, elementType);
|
||||
Object convertedElement = convertIfNecessary(
|
||||
indexedPropertyName, null, element, elementType, typeDescriptor);
|
||||
if (methodParam != null) {
|
||||
methodParam.decreaseNestingLevel();
|
||||
}
|
||||
@@ -651,11 +653,11 @@ class TypeConverterDelegate {
|
||||
methodParam.increaseNestingLevel();
|
||||
methodParam.setTypeIndexForCurrentLevel(0);
|
||||
}
|
||||
Object convertedKey = convertIfNecessary(keyedPropertyName, null, key, keyType);
|
||||
Object convertedKey = convertIfNecessary(keyedPropertyName, null, key, keyType, typeDescriptor);
|
||||
if (methodParam != null) {
|
||||
methodParam.setTypeIndexForCurrentLevel(1);
|
||||
}
|
||||
Object convertedValue = convertIfNecessary(keyedPropertyName, null, value, valueType);
|
||||
Object convertedValue = convertIfNecessary(keyedPropertyName, null, value, valueType, typeDescriptor);
|
||||
if (methodParam != null) {
|
||||
methodParam.decreaseNestingLevel();
|
||||
}
|
||||
|
||||
@@ -103,8 +103,6 @@ public class TypeDescriptor {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
// protected constructors for subclasses
|
||||
|
||||
/**
|
||||
* Create a new type descriptor from a method or constructor parameter.
|
||||
* <p>Use this constructor when a target conversion point originates from a method parameter,
|
||||
@@ -112,12 +110,23 @@ public class TypeDescriptor {
|
||||
* @param methodParameter the MethodParameter to wrap
|
||||
* @param type the specific type to expose (may be an array/collection element)
|
||||
*/
|
||||
protected TypeDescriptor(MethodParameter methodParameter, Class<?> type) {
|
||||
public TypeDescriptor(MethodParameter methodParameter, Class<?> type) {
|
||||
Assert.notNull(methodParameter, "MethodParameter must not be null");
|
||||
this.methodParameter = methodParameter;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a field.
|
||||
* Use this constructor when a target conversion point originates from a field.
|
||||
* @param field the field to wrap
|
||||
*/
|
||||
public TypeDescriptor(Field field, Class<?> type) {
|
||||
Assert.notNull(field, "Field must not be null");
|
||||
this.field = field;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor for a NULL descriptor.
|
||||
*/
|
||||
@@ -227,24 +236,43 @@ public class TypeDescriptor {
|
||||
|
||||
/**
|
||||
* If this type is an array type or {@link Collection} type, returns the underlying element type.
|
||||
* Returns null if the type is neither an array or collection.
|
||||
* Returns <code>null</code> if the type is neither an array or collection.
|
||||
*/
|
||||
public Class<?> getElementType() {
|
||||
return getElementTypeDescriptor().getType();
|
||||
if (isArray()) {
|
||||
return getArrayComponentType();
|
||||
}
|
||||
else if (isCollection()) {
|
||||
return getCollectionElementType();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the element type as a type descriptor.
|
||||
*/
|
||||
public TypeDescriptor getElementTypeDescriptor() {
|
||||
if (isArray()) {
|
||||
return TypeDescriptor.valueOf(getArrayComponentType());
|
||||
return TypeDescriptor.valueOf(getElementType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this type descriptor, preserving the context information
|
||||
* but exposing the specified element type (e.g. an array/collection element).
|
||||
* @param elementType the desired type to expose
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public TypeDescriptor forElementType(Class<?> elementType) {
|
||||
Assert.notNull(elementType, "Element type must not be null");
|
||||
if (getType().equals(elementType)) {
|
||||
return this;
|
||||
}
|
||||
else if (isCollection()) {
|
||||
return TypeDescriptor.valueOf(getCollectionElementType());
|
||||
else if (this.methodParameter != null) {
|
||||
return new TypeDescriptor(this.methodParameter, elementType);
|
||||
}
|
||||
else {
|
||||
return TypeDescriptor.NULL;
|
||||
return new TypeDescriptor(this.field, elementType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public class PropertyTypeDescriptor extends TypeDescriptor {
|
||||
* @param methodParameter the target method parameter
|
||||
* @param type the specific type to expose (may be an array/collection element)
|
||||
*/
|
||||
public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter, Class type) {
|
||||
public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter, Class<?> type) {
|
||||
super(methodParameter, type);
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user