completed generic converter implementation
This commit is contained in:
parent
ce800fb45a
commit
7a6dafd5ad
|
|
@ -44,6 +44,8 @@ public class TypeDescriptor {
|
||||||
|
|
||||||
private Class<?> type;
|
private Class<?> type;
|
||||||
|
|
||||||
|
private TypeDescriptor elementType;
|
||||||
|
|
||||||
private MethodParameter methodParameter;
|
private MethodParameter methodParameter;
|
||||||
|
|
||||||
private Field field;
|
private Field field;
|
||||||
|
|
@ -88,6 +90,11 @@ public class TypeDescriptor {
|
||||||
private TypeDescriptor() {
|
private TypeDescriptor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeDescriptor(Class collectionType, TypeDescriptor elementType) {
|
||||||
|
this.type = collectionType;
|
||||||
|
this.elementType = elementType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the wrapped MethodParameter, if any.
|
* Return the wrapped MethodParameter, if any.
|
||||||
* <p>Note: Either MethodParameter or Field is available.
|
* <p>Note: Either MethodParameter or Field is available.
|
||||||
|
|
@ -113,14 +120,11 @@ public class TypeDescriptor {
|
||||||
public Class<?> getType() {
|
public Class<?> getType() {
|
||||||
if (this.type != null) {
|
if (this.type != null) {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
} else if (this.field != null) {
|
||||||
else if (this.field != null) {
|
|
||||||
return this.field.getType();
|
return this.field.getType();
|
||||||
}
|
} else if (this.methodParameter != null) {
|
||||||
else if (this.methodParameter != null) {
|
|
||||||
return this.methodParameter.getParameterType();
|
return this.methodParameter.getParameterType();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +138,15 @@ public class TypeDescriptor {
|
||||||
return type != null ? ClassUtils.resolvePrimitiveIfNecessary(type) : type;
|
return type != null ? ClassUtils.resolvePrimitiveIfNecessary(type) : type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the underyling declared type equal the type provided?
|
||||||
|
* @param type the type to test against
|
||||||
|
*/
|
||||||
|
public boolean typeEquals(Class<?> type) {
|
||||||
|
Class<?> thisType = getType();
|
||||||
|
return thisType != null ? thisType.equals(type) : false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of this type; the fully qualified classname.
|
* Returns the name of this type; the fully qualified classname.
|
||||||
*/
|
*/
|
||||||
|
|
@ -141,8 +154,7 @@ public class TypeDescriptor {
|
||||||
Class<?> type = getType();
|
Class<?> type = getType();
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
return getType().getName();
|
return getType().getName();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,22 +179,24 @@ public class TypeDescriptor {
|
||||||
* Returns null if the type is neither an array or collection.
|
* Returns null if the type is neither an array or collection.
|
||||||
*/
|
*/
|
||||||
public Class<?> getElementType() {
|
public Class<?> getElementType() {
|
||||||
if (isArray()) {
|
return getElementTypeDescriptor().getType();
|
||||||
return getArrayComponentType();
|
|
||||||
}
|
|
||||||
else if (isCollection()) {
|
|
||||||
return getCollectionElementType();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the element type as a type descriptor.
|
* Return the element type as a type descriptor.
|
||||||
*/
|
*/
|
||||||
public TypeDescriptor getElementTypeDescriptor() {
|
public TypeDescriptor getElementTypeDescriptor() {
|
||||||
return TypeDescriptor.valueOf(getElementType());
|
if (elementType != null) {
|
||||||
|
return elementType;
|
||||||
|
} else {
|
||||||
|
if (isArray()) {
|
||||||
|
return TypeDescriptor.valueOf(getArrayComponentType());
|
||||||
|
} else if (isCollection()) {
|
||||||
|
return TypeDescriptor.valueOf(getCollectionElementType());
|
||||||
|
} else {
|
||||||
|
return TypeDescriptor.NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -191,7 +205,7 @@ public class TypeDescriptor {
|
||||||
public boolean isMap() {
|
public boolean isMap() {
|
||||||
return isTypeAssignableTo(Map.class);
|
return isTypeAssignableTo(Map.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this descriptor for a map where the key type and value type are known?
|
* Is this descriptor for a map where the key type and value type are known?
|
||||||
*/
|
*/
|
||||||
|
|
@ -206,11 +220,9 @@ public class TypeDescriptor {
|
||||||
public Class<?> getMapKeyType() {
|
public Class<?> getMapKeyType() {
|
||||||
if (this.field != null) {
|
if (this.field != null) {
|
||||||
return GenericCollectionTypeResolver.getMapKeyFieldType(field);
|
return GenericCollectionTypeResolver.getMapKeyFieldType(field);
|
||||||
}
|
} else if (this.methodParameter != null) {
|
||||||
else if (this.methodParameter != null) {
|
|
||||||
return GenericCollectionTypeResolver.getMapKeyParameterType(this.methodParameter);
|
return GenericCollectionTypeResolver.getMapKeyParameterType(this.methodParameter);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,11 +234,9 @@ public class TypeDescriptor {
|
||||||
public Class<?> getMapValueType() {
|
public Class<?> getMapValueType() {
|
||||||
if (this.field != null) {
|
if (this.field != null) {
|
||||||
return GenericCollectionTypeResolver.getMapValueFieldType(this.field);
|
return GenericCollectionTypeResolver.getMapValueFieldType(this.field);
|
||||||
}
|
} else if (this.methodParameter != null) {
|
||||||
else if (this.methodParameter != null) {
|
|
||||||
return GenericCollectionTypeResolver.getMapValueParameterType(this.methodParameter);
|
return GenericCollectionTypeResolver.getMapValueParameterType(this.methodParameter);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,11 +264,9 @@ public class TypeDescriptor {
|
||||||
this.cachedFieldAnnotations = this.field.getAnnotations();
|
this.cachedFieldAnnotations = this.field.getAnnotations();
|
||||||
}
|
}
|
||||||
return this.cachedFieldAnnotations;
|
return this.cachedFieldAnnotations;
|
||||||
}
|
} else if (this.methodParameter != null) {
|
||||||
else if (this.methodParameter != null) {
|
|
||||||
return this.methodParameter.getMethod().getAnnotations();
|
return this.methodParameter.getMethod().getAnnotations();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return new Annotation[0];
|
return new Annotation[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -300,10 +308,9 @@ public class TypeDescriptor {
|
||||||
if (isArray()) {
|
if (isArray()) {
|
||||||
// TODO should properly handle multi dimensional arrays
|
// TODO should properly handle multi dimensional arrays
|
||||||
stringValue.append(getArrayComponentType().getName()).append("[]");
|
stringValue.append(getArrayComponentType().getName()).append("[]");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Class<?> clazz = getType();
|
Class<?> clazz = getType();
|
||||||
if (clazz==null) {
|
if (clazz == null) {
|
||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
stringValue.append(clazz.getName());
|
stringValue.append(clazz.getName());
|
||||||
|
|
@ -312,8 +319,7 @@ public class TypeDescriptor {
|
||||||
if (collectionType != null) {
|
if (collectionType != null) {
|
||||||
stringValue.append("<").append(collectionType.getName()).append(">");
|
stringValue.append("<").append(collectionType.getName()).append(">");
|
||||||
}
|
}
|
||||||
}
|
} else if (isMap()) {
|
||||||
else if (isMap()) {
|
|
||||||
Class<?> keyType = getMapKeyType();
|
Class<?> keyType = getMapKeyType();
|
||||||
Class<?> valType = getMapValueType();
|
Class<?> valType = getMapValueType();
|
||||||
if (keyType != null && valType != null) {
|
if (keyType != null && valType != null) {
|
||||||
|
|
@ -325,7 +331,6 @@ public class TypeDescriptor {
|
||||||
return stringValue.toString();
|
return stringValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// internal helpers
|
// internal helpers
|
||||||
|
|
||||||
private Class<?> getArrayComponentType() {
|
private Class<?> getArrayComponentType() {
|
||||||
|
|
@ -336,21 +341,18 @@ public class TypeDescriptor {
|
||||||
private Class<?> getCollectionElementType() {
|
private Class<?> getCollectionElementType() {
|
||||||
if (this.type != null) {
|
if (this.type != null) {
|
||||||
return GenericCollectionTypeResolver.getCollectionType((Class<? extends Collection>) this.type);
|
return GenericCollectionTypeResolver.getCollectionType((Class<? extends Collection>) this.type);
|
||||||
}
|
} else if (this.field != null) {
|
||||||
else if (this.field != null) {
|
|
||||||
return GenericCollectionTypeResolver.getCollectionFieldType(this.field);
|
return GenericCollectionTypeResolver.getCollectionFieldType(this.field);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return GenericCollectionTypeResolver.getCollectionParameterType(this.methodParameter);
|
return GenericCollectionTypeResolver.getCollectionParameterType(this.methodParameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTypeAssignableTo(Class<?> clazz) {
|
private boolean isTypeAssignableTo(Class<?> clazz) {
|
||||||
Class<?> type = getType();
|
Class<?> type = getType();
|
||||||
return (type != null && ClassUtils.isAssignable(clazz, type));
|
return (type != null && ClassUtils.isAssignable(clazz, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static factory methods
|
// static factory methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -371,4 +373,16 @@ public class TypeDescriptor {
|
||||||
return (object == null ? NULL : valueOf(object.getClass()));
|
return (object == null ? NULL : valueOf(object.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (this == TypeDescriptor.NULL) {
|
||||||
|
return "[TypeDescriptor.NULL]";
|
||||||
|
} else {
|
||||||
|
return "[TypeDescriptor type=" + getType().getName() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TypeDescriptor collection(Class<?> type, TypeDescriptor elementType) {
|
||||||
|
return new TypeDescriptor(type, elementType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,38 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
import static org.springframework.core.convert.support.ConversionUtils.asList;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
final class ArrayToArrayGenericConverter implements GenericConverter {
|
final class ArrayToArrayGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
private final GenericConverter helperConverter;
|
||||||
|
|
||||||
public ArrayToArrayGenericConverter(GenericConversionService conversionService) {
|
public ArrayToArrayGenericConverter(GenericConversionService conversionService) {
|
||||||
this.conversionService = conversionService;
|
this.helperConverter = new CollectionToArrayGenericConverter(conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
if (sourceType.isAssignableTo(targetType)) {
|
return this.helperConverter.convert(asList(source), sourceType, targetType);
|
||||||
return source;
|
|
||||||
}
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
|
||||||
Object target = Array.newInstance(targetElementType.getType(), Array.getLength(source));
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetElementType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceElementType, targetElementType);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < Array.getLength(target); i++) {
|
|
||||||
Object sourceElement = Array.get(source, i);
|
|
||||||
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetElementType);
|
|
||||||
Array.set(target, i, targetElement);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import static org.springframework.core.convert.support.ConversionUtils.asList;
|
||||||
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
final class StringToMapGenericConverter implements GenericConverter {
|
final class ArrayToMapGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
private final StringArrayToMapGenericConverter converter;
|
private final GenericConverter helperConverter;
|
||||||
|
|
||||||
public StringToMapGenericConverter(GenericConversionService conversionService) {
|
public ArrayToMapGenericConverter(GenericConversionService conversionService) {
|
||||||
this.converter = new StringArrayToMapGenericConverter(conversionService);
|
this.helperConverter = new CollectionToMapGenericConverter(conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
String string = (String) source;
|
return this.helperConverter.convert(asList(source), sourceType, targetType);
|
||||||
String[] properties = string.split(" ");
|
|
||||||
return this.converter.convert(properties, TypeDescriptor.valueOf(String[].class), targetType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -15,37 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
import static org.springframework.core.convert.support.ConversionUtils.asList;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
final class ArrayToObjectGenericConverter implements GenericConverter {
|
final class ArrayToObjectGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
private CollectionToObjectGenericConverter helperConverter;
|
||||||
|
|
||||||
public ArrayToObjectGenericConverter(GenericConversionService conversionService) {
|
public ArrayToObjectGenericConverter(GenericConversionService conversionService) {
|
||||||
this.conversionService = conversionService;
|
this.helperConverter = new CollectionToObjectGenericConverter(conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
int length = Array.getLength(source);
|
return this.helperConverter.convert(asList(source), sourceType, targetType);
|
||||||
if (length == 0) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
if (sourceElementType.isAssignableTo(targetType)) {
|
|
||||||
return Array.get(source, 0);
|
|
||||||
} else {
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceElementType, targetType);
|
|
||||||
}
|
|
||||||
return invokeConverter(converter, Array.get(source, 0), sourceElementType, targetType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.core.convert.support;
|
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
|
|
||||||
final class ArrayToStringGenericConverter implements GenericConverter {
|
|
||||||
|
|
||||||
private static final String DELIMITER = ",";
|
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
|
||||||
|
|
||||||
public ArrayToStringGenericConverter(GenericConversionService conversionService) {
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
int length = Array.getLength(source);
|
|
||||||
if (length == 0) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
if (sourceElementType.isAssignableTo(targetType)) {
|
|
||||||
StringBuilder string = new StringBuilder();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
string.append(DELIMITER);
|
|
||||||
}
|
|
||||||
string.append(Array.get(source, i));
|
|
||||||
}
|
|
||||||
return string.toString();
|
|
||||||
} else {
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceElementType, targetType);
|
|
||||||
}
|
|
||||||
StringBuilder string = new StringBuilder();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
string.append(DELIMITER);
|
|
||||||
}
|
|
||||||
Object sourceElement = Array.get(source, i);
|
|
||||||
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetType);
|
|
||||||
string.append(targetElement);
|
|
||||||
}
|
|
||||||
return string.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.core.CollectionFactory;
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
|
final class CollectionToMapGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
private final GenericConversionService conversionService;
|
||||||
|
|
||||||
|
public CollectionToMapGenericConverter(GenericConversionService conversionService) {
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
|
Collection sourceCollection = (Collection) source;
|
||||||
|
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL) {
|
||||||
|
sourceElementType = getElementType(sourceCollection);
|
||||||
|
}
|
||||||
|
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
|
||||||
|
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
|
||||||
|
boolean keysCompatible = false;
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL || targetKeyType == TypeDescriptor.NULL
|
||||||
|
|| sourceElementType.isAssignableTo(targetKeyType)) {
|
||||||
|
keysCompatible = true;
|
||||||
|
}
|
||||||
|
boolean valuesCompatible = false;
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL || targetValueType == TypeDescriptor.NULL
|
||||||
|
|| sourceElementType.isAssignableTo(targetValueType)) {
|
||||||
|
valuesCompatible = true;
|
||||||
|
}
|
||||||
|
if (keysCompatible && valuesCompatible) {
|
||||||
|
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size());
|
||||||
|
if (sourceElementType.typeEquals(String.class)) {
|
||||||
|
for (Object element : sourceCollection) {
|
||||||
|
String[] property = parseProperty((String) element);
|
||||||
|
target.put(property[0], property[1]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Object element : sourceCollection) {
|
||||||
|
target.put(element, element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
} else {
|
||||||
|
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size());
|
||||||
|
MapEntryConverter converter = new MapEntryConverter(sourceElementType, sourceElementType, targetKeyType,
|
||||||
|
targetValueType, keysCompatible, valuesCompatible, conversionService);
|
||||||
|
if (sourceElementType.typeEquals(String.class)) {
|
||||||
|
for (Object element : sourceCollection) {
|
||||||
|
String[] property = parseProperty((String) element);
|
||||||
|
Object targetKey = converter.convertKey(property[0]);
|
||||||
|
Object targetValue = converter.convertValue(property[1]);
|
||||||
|
target.put(targetKey, targetValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Object element : sourceCollection) {
|
||||||
|
Object targetKey = converter.convertKey(element);
|
||||||
|
Object targetValue = converter.convertValue(element);
|
||||||
|
target.put(targetKey, targetValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] parseProperty(String string) {
|
||||||
|
String[] property = string.split("=");
|
||||||
|
if (property.length < 2) {
|
||||||
|
throw new IllegalArgumentException("Invalid String property '" + property
|
||||||
|
+ "'; properties should be in the format name=value");
|
||||||
|
}
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -24,6 +25,8 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
final class CollectionToObjectGenericConverter implements GenericConverter {
|
final class CollectionToObjectGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
private static final String DELIMITER = ",";
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
private final GenericConversionService conversionService;
|
||||||
|
|
||||||
public CollectionToObjectGenericConverter(GenericConversionService conversionService) {
|
public CollectionToObjectGenericConverter(GenericConversionService conversionService) {
|
||||||
|
|
@ -33,21 +36,60 @@ final class CollectionToObjectGenericConverter implements GenericConverter {
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
Collection sourceCollection = (Collection) source;
|
Collection sourceCollection = (Collection) source;
|
||||||
if (sourceCollection.size() == 0) {
|
if (sourceCollection.size() == 0) {
|
||||||
return null;
|
if (targetType.typeEquals(String.class)) {
|
||||||
} else {
|
return "";
|
||||||
Object firstElement = sourceCollection.iterator().next();
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
if (sourceElementType == TypeDescriptor.NULL && firstElement != null) {
|
|
||||||
sourceElementType = TypeDescriptor.valueOf(firstElement.getClass());
|
|
||||||
}
|
|
||||||
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
|
|
||||||
return firstElement;
|
|
||||||
} else {
|
} else {
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
return null;
|
||||||
if (converter == null) {
|
}
|
||||||
throw new ConverterNotFoundException(sourceElementType, targetType);
|
} else {
|
||||||
}
|
if (targetType.typeEquals(String.class)) {
|
||||||
return invokeConverter(converter, firstElement, sourceElementType, targetType);
|
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL) {
|
||||||
|
sourceElementType = getElementType(sourceCollection);
|
||||||
|
}
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
|
||||||
|
StringBuilder string = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (Object element : sourceCollection) {
|
||||||
|
if (i > 0) {
|
||||||
|
string.append(DELIMITER);
|
||||||
|
}
|
||||||
|
string.append(element);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return string.toString();
|
||||||
|
} else {
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceElementType, targetType);
|
||||||
|
}
|
||||||
|
StringBuilder string = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (Object sourceElement : sourceCollection) {
|
||||||
|
if (i > 0) {
|
||||||
|
string.append(DELIMITER);
|
||||||
|
}
|
||||||
|
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetType);
|
||||||
|
string.append(targetElement);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return string.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Object firstElement = sourceCollection.iterator().next();
|
||||||
|
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL && firstElement != null) {
|
||||||
|
sourceElementType = TypeDescriptor.valueOf(firstElement.getClass());
|
||||||
|
}
|
||||||
|
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
|
||||||
|
return firstElement;
|
||||||
|
} else {
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceElementType, targetType);
|
||||||
|
}
|
||||||
|
return invokeConverter(converter, firstElement, sourceElementType, targetType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.core.convert.support;
|
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
|
|
||||||
final class CollectionToStringGenericConverter implements GenericConverter {
|
|
||||||
|
|
||||||
private static final String DELIMITER = ",";
|
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
|
||||||
|
|
||||||
public CollectionToStringGenericConverter(GenericConversionService conversionService) {
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
Collection sourceCollection = (Collection) source;
|
|
||||||
if (sourceCollection.size() == 0) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
if (sourceElementType == TypeDescriptor.NULL) {
|
|
||||||
sourceElementType = getElementType(sourceCollection);
|
|
||||||
}
|
|
||||||
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
|
|
||||||
StringBuilder string = new StringBuilder();
|
|
||||||
int i = 0;
|
|
||||||
for (Object element : sourceCollection) {
|
|
||||||
if (i > 0) {
|
|
||||||
string.append(DELIMITER);
|
|
||||||
}
|
|
||||||
string.append(element);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return string.toString();
|
|
||||||
} else {
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceElementType, targetType);
|
|
||||||
}
|
|
||||||
StringBuilder string = new StringBuilder();
|
|
||||||
int i = 0;
|
|
||||||
for (Object sourceElement : sourceCollection) {
|
|
||||||
if (i > 0) {
|
|
||||||
string.append(DELIMITER);
|
|
||||||
}
|
|
||||||
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetType);
|
|
||||||
string.append(targetElement);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return string.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -15,7 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.AbstractList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.RandomAccess;
|
||||||
|
|
||||||
import org.springframework.core.convert.ConversionFailedException;
|
import org.springframework.core.convert.ConversionFailedException;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
@ -39,4 +43,27 @@ final class ConversionUtils {
|
||||||
}
|
}
|
||||||
return TypeDescriptor.NULL;
|
return TypeDescriptor.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List asList(Object array) {
|
||||||
|
return new ArrayList(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ArrayList extends AbstractList implements RandomAccess, java.io.Serializable {
|
||||||
|
|
||||||
|
private Object array;
|
||||||
|
|
||||||
|
ArrayList(Object array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return Array.getLength(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int index) {
|
||||||
|
return Array.get(array, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,27 +182,21 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
||||||
* Hook to initialize the "generic" converters that require the full TypeDescriptor context to perform their conversion operations.
|
* Hook to initialize the "generic" converters that require the full TypeDescriptor context to perform their conversion operations.
|
||||||
*/
|
*/
|
||||||
protected void initGenericConverters() {
|
protected void initGenericConverters() {
|
||||||
addGenericConverter(String[].class, Map.class, new StringArrayToMapGenericConverter(this));
|
|
||||||
addGenericConverter(Object[].class, Object[].class, new ArrayToArrayGenericConverter(this));
|
addGenericConverter(Object[].class, Object[].class, new ArrayToArrayGenericConverter(this));
|
||||||
addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionGenericConverter(this));
|
addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionGenericConverter(this));
|
||||||
addGenericConverter(Object[].class, String.class, new ArrayToStringGenericConverter(this));
|
addGenericConverter(Object[].class, Map.class, new ArrayToMapGenericConverter(this));
|
||||||
addGenericConverter(Object[].class, Object.class, new ArrayToObjectGenericConverter(this));
|
addGenericConverter(Object[].class, Object.class, new ArrayToObjectGenericConverter(this));
|
||||||
// TODO Collection->Map
|
|
||||||
addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionGenericConverter(this));
|
addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionGenericConverter(this));
|
||||||
addGenericConverter(Collection.class, Object[].class, new CollectionToArrayGenericConverter(this));
|
addGenericConverter(Collection.class, Object[].class, new CollectionToArrayGenericConverter(this));
|
||||||
addGenericConverter(Collection.class, String.class, new CollectionToStringGenericConverter(this));
|
addGenericConverter(Collection.class, Map.class, new CollectionToMapGenericConverter(this));
|
||||||
addGenericConverter(Collection.class, Object.class, new CollectionToObjectGenericConverter(this));
|
addGenericConverter(Collection.class, Object.class, new CollectionToObjectGenericConverter(this));
|
||||||
addGenericConverter(Map.class, Map.class, new MapToMapGenericConverter(this));
|
addGenericConverter(Map.class, Map.class, new MapToMapGenericConverter(this));
|
||||||
addGenericConverter(Map.class, String[].class, new MapToStringArrayGenericConverter(this));
|
addGenericConverter(Map.class, Object[].class, new MapToArrayGenericConverter(this));
|
||||||
// TODO Map->Collection
|
addGenericConverter(Map.class, Collection.class, new MapToCollectionGenericConverter(this));
|
||||||
// TODO Map->String
|
addGenericConverter(Map.class, Object.class, new MapToObjectGenericConverter(this));
|
||||||
// TODO Map->Object
|
|
||||||
addGenericConverter(String.class, Object[].class, new StringToArrayGenericConverter(this));
|
|
||||||
addGenericConverter(String.class, Collection.class, new StringToCollectionGenericConverter(this));
|
|
||||||
addGenericConverter(String.class, Map.class, new StringToMapGenericConverter(this));
|
|
||||||
addGenericConverter(Object.class, Object[].class, new ObjectToArrayGenericConverter(this));
|
addGenericConverter(Object.class, Object[].class, new ObjectToArrayGenericConverter(this));
|
||||||
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this));
|
addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this));
|
||||||
// TODO Object->Map
|
addGenericConverter(Object.class, Map.class, new ObjectToMapGenericConverter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
|
final class MapToArrayGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
private final GenericConverter mapToCollectionHelperConverter;
|
||||||
|
|
||||||
|
private final GenericConverter collectionToArrayHelperConverter;
|
||||||
|
|
||||||
|
public MapToArrayGenericConverter(GenericConversionService conversionService) {
|
||||||
|
this.mapToCollectionHelperConverter = new MapToCollectionGenericConverter(conversionService);
|
||||||
|
this.collectionToArrayHelperConverter = new CollectionToArrayGenericConverter(conversionService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
|
TypeDescriptor collectionType = TypeDescriptor.collection(List.class, targetType.getElementTypeDescriptor());
|
||||||
|
Object collection = this.mapToCollectionHelperConverter.convert(source, sourceType, collectionType);
|
||||||
|
return this.collectionToArrayHelperConverter.convert(collection, collectionType, targetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -15,44 +15,49 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
final class MapToStringArrayGenericConverter implements GenericConverter {
|
final class MapToCollectionGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
private final GenericConversionService conversionService;
|
||||||
|
|
||||||
public MapToStringArrayGenericConverter(GenericConversionService conversionService) {
|
public MapToCollectionGenericConverter(GenericConversionService conversionService) {
|
||||||
this.conversionService = conversionService;
|
this.conversionService = conversionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
Map sourceMap = (Map) source;
|
Map sourceMap = (Map) source;
|
||||||
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
|
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
|
||||||
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
|
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
||||||
boolean keysCompatible = false;
|
boolean keysCompatible = false;
|
||||||
if (sourceKeyType.isAssignableTo(targetElementType)) {
|
if (targetElementType == TypeDescriptor.NULL || sourceKeyType.isAssignableTo(targetElementType)) {
|
||||||
keysCompatible = true;
|
keysCompatible = true;
|
||||||
}
|
}
|
||||||
boolean valuesCompatible = false;
|
boolean valuesCompatible = false;
|
||||||
if (sourceValueType.isAssignableTo(targetElementType)) {
|
if (targetElementType == TypeDescriptor.NULL || sourceValueType.isAssignableTo(targetElementType)) {
|
||||||
valuesCompatible = true;
|
valuesCompatible = true;
|
||||||
}
|
|
||||||
Object array = Array.newInstance(targetElementType.getType(), sourceMap.size());
|
|
||||||
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetElementType, targetElementType, keysCompatible, valuesCompatible, conversionService);
|
|
||||||
int i = 0;
|
|
||||||
for (Object entry : sourceMap.entrySet()) {
|
|
||||||
Map.Entry mapEntry = (Map.Entry) entry;
|
|
||||||
Object key = mapEntry.getKey();
|
|
||||||
Object value = mapEntry.getValue();
|
|
||||||
String property = converter.convertKey(key) + "=" + converter.convertValue(value);
|
|
||||||
Array.set(array, i, property);
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
return array;
|
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceMap.size());
|
||||||
|
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetElementType,
|
||||||
|
targetElementType, keysCompatible, valuesCompatible, conversionService);
|
||||||
|
if (targetElementType.getType().equals(String.class)) {
|
||||||
|
for (Object entry : sourceMap.entrySet()) {
|
||||||
|
Map.Entry mapEntry = (Map.Entry) entry;
|
||||||
|
String property = converter.convertKey(mapEntry.getKey()) + "="
|
||||||
|
+ converter.convertValue(mapEntry.getValue());
|
||||||
|
target.add(property);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Object value : sourceMap.values()) {
|
||||||
|
target.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package org.springframework.core.convert.support;
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
|
|
@ -28,22 +27,25 @@ final class MapToMapGenericConverter implements GenericConverter {
|
||||||
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
|
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
|
||||||
}
|
}
|
||||||
boolean keysCompatible = false;
|
boolean keysCompatible = false;
|
||||||
if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL && sourceKeyType.isAssignableTo(targetKeyType)) {
|
if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL
|
||||||
|
&& sourceKeyType.isAssignableTo(targetKeyType)) {
|
||||||
keysCompatible = true;
|
keysCompatible = true;
|
||||||
}
|
}
|
||||||
boolean valuesCompatible = false;
|
boolean valuesCompatible = false;
|
||||||
if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL && sourceValueType.isAssignableTo(targetValueType)) {
|
if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL
|
||||||
|
&& sourceValueType.isAssignableTo(targetValueType)) {
|
||||||
valuesCompatible = true;
|
valuesCompatible = true;
|
||||||
}
|
}
|
||||||
if (keysCompatible && valuesCompatible) {
|
if (keysCompatible && valuesCompatible) {
|
||||||
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
|
return compatibleMapWithoutEntryConversion(sourceMap, targetType);
|
||||||
}
|
}
|
||||||
Map targetMap = CollectionFactory.createMap(targetType.getType(), sourceMap.size());
|
Map targetMap = CollectionFactory.createMap(targetType.getType(), sourceMap.size());
|
||||||
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetKeyType, targetValueType, keysCompatible, valuesCompatible, conversionService);
|
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetKeyType,
|
||||||
|
targetValueType, keysCompatible, valuesCompatible, conversionService);
|
||||||
for (Object entry : sourceMap.entrySet()) {
|
for (Object entry : sourceMap.entrySet()) {
|
||||||
Map.Entry sourceMapEntry = (Map.Entry) entry;
|
Map.Entry sourceMapEntry = (Map.Entry) entry;
|
||||||
Object targetKey = converter.convertKey(sourceMapEntry.getKey());
|
Object targetKey = converter.convertKey(sourceMapEntry.getKey());
|
||||||
Object targetValue = converter.convertValue(sourceMapEntry.getValue());
|
Object targetValue = converter.convertValue(sourceMapEntry.getValue());
|
||||||
targetMap.put(targetKey, targetValue);
|
targetMap.put(targetKey, targetValue);
|
||||||
}
|
}
|
||||||
return targetMap;
|
return targetMap;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
|
final class MapToObjectGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
private static final String DELIMITER = " ";
|
||||||
|
|
||||||
|
private final GenericConversionService conversionService;
|
||||||
|
|
||||||
|
public MapToObjectGenericConverter(GenericConversionService conversionService) {
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
|
Map sourceMap = (Map) source;
|
||||||
|
if (sourceMap.size() == 0) {
|
||||||
|
if (targetType.typeEquals(String.class)) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (targetType.typeEquals(String.class)) {
|
||||||
|
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
|
||||||
|
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
|
||||||
|
boolean keysCompatible = false;
|
||||||
|
if (sourceKeyType == TypeDescriptor.NULL || sourceKeyType.isAssignableTo(targetType)) {
|
||||||
|
keysCompatible = true;
|
||||||
|
}
|
||||||
|
boolean valuesCompatible = false;
|
||||||
|
if (sourceValueType == TypeDescriptor.NULL || sourceValueType.isAssignableTo(targetType)) {
|
||||||
|
valuesCompatible = true;
|
||||||
|
}
|
||||||
|
if (keysCompatible && valuesCompatible) {
|
||||||
|
StringBuilder string = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (Object entry : sourceMap.entrySet()) {
|
||||||
|
Map.Entry mapEntry = (Map.Entry) entry;
|
||||||
|
if (i > 0) {
|
||||||
|
string.append(DELIMITER);
|
||||||
|
}
|
||||||
|
String property = mapEntry.getKey() + "=" + mapEntry.getValue();
|
||||||
|
string.append(property);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return string.toString();
|
||||||
|
} else {
|
||||||
|
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetType, targetType,
|
||||||
|
keysCompatible, valuesCompatible, conversionService);
|
||||||
|
StringBuilder string = new StringBuilder();
|
||||||
|
int i = 0;
|
||||||
|
for (Object entry : sourceMap.entrySet()) {
|
||||||
|
Map.Entry mapEntry = (Map.Entry) entry;
|
||||||
|
if (i > 0) {
|
||||||
|
string.append(DELIMITER);
|
||||||
|
}
|
||||||
|
Object key = converter.convertKey(mapEntry.getKey());
|
||||||
|
Object value = converter.convertValue(mapEntry.getValue());
|
||||||
|
String property = key + "=" + value;
|
||||||
|
string.append(property);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return string.toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
|
||||||
|
boolean valuesCompatible = false;
|
||||||
|
if (sourceValueType == TypeDescriptor.NULL || sourceValueType.isAssignableTo(targetType)) {
|
||||||
|
valuesCompatible = true;
|
||||||
|
}
|
||||||
|
if (valuesCompatible) {
|
||||||
|
return sourceMap.values().iterator().next();
|
||||||
|
} else {
|
||||||
|
MapEntryConverter converter = new MapEntryConverter(sourceValueType, sourceValueType, targetType, targetType,
|
||||||
|
true, valuesCompatible, conversionService);
|
||||||
|
Object value = sourceMap.values().iterator().next();
|
||||||
|
return converter.convertValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.Array;
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
import org.springframework.core.convert.ConverterNotFoundException;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
final class ObjectToArrayGenericConverter implements GenericConverter {
|
final class ObjectToArrayGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
|
@ -32,17 +33,35 @@ final class ObjectToArrayGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
||||||
Object target = Array.newInstance(targetElementType.getType(), 1);
|
if (sourceType.typeEquals(String.class)) {
|
||||||
if (sourceType.isAssignableTo(targetElementType)) {
|
String string = (String) source;
|
||||||
Array.set(target, 0, source);
|
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
|
||||||
} else {
|
if (sourceType.isAssignableTo(targetElementType)) {
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
return fields;
|
||||||
if (converter == null) {
|
} else {
|
||||||
throw new ConverterNotFoundException(sourceType, targetElementType);
|
Object target = Array.newInstance(targetElementType.getType(), fields.length);
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceType, targetElementType);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Array.set(target, i, invokeConverter(converter, fields[i], sourceType, targetElementType));
|
||||||
|
}
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
Array.set(target, 0, invokeConverter(converter, source, sourceType, targetElementType));
|
} else {
|
||||||
|
Object target = Array.newInstance(targetElementType.getType(), 1);
|
||||||
|
if (sourceType.isAssignableTo(targetElementType)) {
|
||||||
|
Array.set(target, 0, source);
|
||||||
|
} else {
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceType, targetElementType);
|
||||||
|
}
|
||||||
|
Array.set(target, 0, invokeConverter(converter, source, sourceType, targetElementType));
|
||||||
|
}
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ import java.util.Collection;
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
import org.springframework.core.convert.ConverterNotFoundException;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
final class ObjectToCollectionGenericConverter implements GenericConverter {
|
final class ObjectToCollectionGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
|
@ -32,18 +33,41 @@ final class ObjectToCollectionGenericConverter implements GenericConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
Collection target = CollectionFactory.createCollection(targetType.getType(), 1);
|
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
||||||
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
|
if (sourceType.typeEquals(String.class)) {
|
||||||
target.add(source);
|
String string = (String) source;
|
||||||
} else {
|
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
Collection target = CollectionFactory.createCollection(targetType.getType(), fields.length);
|
||||||
if (converter == null) {
|
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
|
||||||
throw new ConverterNotFoundException(sourceType, targetElementType);
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
target.add(fields[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceType, targetElementType);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
String sourceElement = fields[i];
|
||||||
|
Object targetElement = invokeConverter(converter, sourceElement, sourceType, targetElementType);
|
||||||
|
target.add(targetElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
target.add(invokeConverter(converter, source, sourceType, targetElementType));
|
return target;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Collection target = CollectionFactory.createCollection(targetType.getType(), 1);
|
||||||
|
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
|
||||||
|
target.add(source);
|
||||||
|
} else {
|
||||||
|
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
||||||
|
if (converter == null) {
|
||||||
|
throw new ConverterNotFoundException(sourceType, targetElementType);
|
||||||
|
}
|
||||||
|
target.add(invokeConverter(converter, source, sourceType, targetElementType));
|
||||||
|
}
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.core.convert.support;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.core.CollectionFactory;
|
||||||
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
|
final class ObjectToMapGenericConverter implements GenericConverter {
|
||||||
|
|
||||||
|
private final GenericConversionService conversionService;
|
||||||
|
|
||||||
|
private final ArrayToMapGenericConverter helperConverter;
|
||||||
|
|
||||||
|
public ObjectToMapGenericConverter(GenericConversionService conversionService) {
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.helperConverter = new ArrayToMapGenericConverter(conversionService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
|
if (sourceType.typeEquals(String.class)) {
|
||||||
|
String string = (String) source;
|
||||||
|
String[] properties = string.split(" ");
|
||||||
|
return this.helperConverter.convert(properties, TypeDescriptor.valueOf(String[].class), targetType);
|
||||||
|
} else {
|
||||||
|
Map target = CollectionFactory.createMap(targetType.getType(), 1);
|
||||||
|
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
|
||||||
|
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
|
||||||
|
boolean keysCompatible = false;
|
||||||
|
if (targetKeyType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetKeyType)) {
|
||||||
|
keysCompatible = true;
|
||||||
|
}
|
||||||
|
boolean valuesCompatible = false;
|
||||||
|
if (targetValueType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetValueType)) {
|
||||||
|
valuesCompatible = true;
|
||||||
|
}
|
||||||
|
if (keysCompatible && valuesCompatible) {
|
||||||
|
target.put(source, source);
|
||||||
|
} else {
|
||||||
|
MapEntryConverter converter = new MapEntryConverter(sourceType, sourceType, targetKeyType,
|
||||||
|
targetValueType, keysCompatible, valuesCompatible, conversionService);
|
||||||
|
Object key = converter.convertKey(source);
|
||||||
|
Object value = converter.convertValue(source);
|
||||||
|
target.put(key, value);
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.core.convert.support;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.core.CollectionFactory;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
|
|
||||||
final class StringArrayToMapGenericConverter implements GenericConverter {
|
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
|
||||||
|
|
||||||
public StringArrayToMapGenericConverter(GenericConversionService conversionService) {
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
|
|
||||||
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
|
|
||||||
if (targetKeyType == TypeDescriptor.NULL && targetValueType == TypeDescriptor.NULL) {
|
|
||||||
return mapWithoutConversion(source, targetType);
|
|
||||||
}
|
|
||||||
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
|
|
||||||
boolean keysCompatible = false;
|
|
||||||
if (sourceElementType.isAssignableTo(targetKeyType)) {
|
|
||||||
keysCompatible = true;
|
|
||||||
}
|
|
||||||
boolean valuesCompatible = false;
|
|
||||||
if (sourceElementType.isAssignableTo(targetValueType)) {
|
|
||||||
valuesCompatible = true;
|
|
||||||
}
|
|
||||||
if (keysCompatible && valuesCompatible) {
|
|
||||||
return mapWithoutConversion(source, targetType);
|
|
||||||
}
|
|
||||||
int length = Array.getLength(source);
|
|
||||||
Map target = CollectionFactory.createMap(targetType.getType(), length);
|
|
||||||
MapEntryConverter converter = new MapEntryConverter(sourceElementType, sourceElementType, targetKeyType, targetValueType, keysCompatible, valuesCompatible, conversionService);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
String property = (String) Array.get(source, i);
|
|
||||||
String[] fields = property.split("=");
|
|
||||||
if (fields.length < 2) {
|
|
||||||
throw new IllegalArgumentException("Invalid String property '" + property
|
|
||||||
+ "'; properties should be in the format name=value");
|
|
||||||
}
|
|
||||||
Object targetKey = converter.convertKey(fields[0]);
|
|
||||||
Object targetValue = converter.convertValue(fields[1]);
|
|
||||||
target.put(targetKey, targetValue);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map mapWithoutConversion(Object source, TypeDescriptor targetType) {
|
|
||||||
int length = Array.getLength(source);
|
|
||||||
Map target = CollectionFactory.createMap(targetType.getType(), length);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
String property = (String) Array.get(source, i);
|
|
||||||
String[] fields = property.split("=");
|
|
||||||
if (fields.length < 2) {
|
|
||||||
throw new IllegalArgumentException("Invalid String property '" + property
|
|
||||||
+ "'; properties should be in the format name=value");
|
|
||||||
}
|
|
||||||
String key = fields[0];
|
|
||||||
String value = fields[1];
|
|
||||||
target.put(key, value);
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.core.convert.support;
|
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
final class StringToArrayGenericConverter implements GenericConverter {
|
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
|
||||||
|
|
||||||
public StringToArrayGenericConverter(GenericConversionService conversionService) {
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
String string = (String) source;
|
|
||||||
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
|
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
|
||||||
if (sourceType.isAssignableTo(targetElementType)) {
|
|
||||||
return fields;
|
|
||||||
} else {
|
|
||||||
Object target = Array.newInstance(targetElementType.getType(), fields.length);
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceType, targetElementType);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
|
||||||
Array.set(target, i, invokeConverter(converter, fields[i], sourceType, targetElementType));
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.core.convert.support;
|
|
||||||
|
|
||||||
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.springframework.core.CollectionFactory;
|
|
||||||
import org.springframework.core.convert.ConverterNotFoundException;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
final class StringToCollectionGenericConverter implements GenericConverter {
|
|
||||||
|
|
||||||
private final GenericConversionService conversionService;
|
|
||||||
|
|
||||||
public StringToCollectionGenericConverter(GenericConversionService conversionService) {
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
String string = (String) source;
|
|
||||||
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
|
|
||||||
Collection target = CollectionFactory.createCollection(targetType.getType(), 1);
|
|
||||||
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
|
|
||||||
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
|
||||||
target.add(fields[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
|
|
||||||
if (converter == null) {
|
|
||||||
throw new ConverterNotFoundException(sourceType, targetElementType);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < fields.length; i++) {
|
|
||||||
String sourceElement = fields[i];
|
|
||||||
Object targetElement = invokeConverter(converter, sourceElement, sourceType, targetElementType);
|
|
||||||
target.add(targetElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -453,6 +453,48 @@ public class GenericConversionServiceTests {
|
||||||
assertEquals(FooEnum.BAZ, result.get(2));
|
assertEquals(FooEnum.BAZ, result.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertMapToString() {
|
||||||
|
Map<String, String> foo = new LinkedHashMap<String, String>();
|
||||||
|
foo.put("1", "BAR");
|
||||||
|
foo.put("2", "BAZ");
|
||||||
|
String result = conversionService.convert(foo, String.class);
|
||||||
|
assertEquals("1=BAR 2=BAZ", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertMapToStringWithConversion() throws Exception {
|
||||||
|
Map<Integer, FooEnum> foo = new LinkedHashMap<Integer, FooEnum>();
|
||||||
|
foo.put(1, FooEnum.BAR);
|
||||||
|
foo.put(2, FooEnum.BAZ);
|
||||||
|
conversionService.addConverter(new ObjectToStringConverter());
|
||||||
|
String result = (String) conversionService.convert(foo, new TypeDescriptor(getClass().getField("genericMap")),
|
||||||
|
TypeDescriptor.valueOf(String.class));
|
||||||
|
assertEquals("1=BAR 2=BAZ", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertMapToObject() {
|
||||||
|
Map<Long, Long> foo = new LinkedHashMap<Long, Long>();
|
||||||
|
foo.put(1L, 1L);
|
||||||
|
foo.put(2L, 2L);
|
||||||
|
Long result = conversionService.convert(foo, Long.class);
|
||||||
|
assertEquals(new Long(1), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Long, Long> genericMap2 = new HashMap<Long, Long>();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertMapToObjectWithConversion() throws Exception {
|
||||||
|
Map<Long, Long> foo = new LinkedHashMap<Long, Long>();
|
||||||
|
foo.put(1L, 1L);
|
||||||
|
foo.put(2L, 2L);
|
||||||
|
conversionService.addConverterFactory(new NumberToNumberConverterFactory());
|
||||||
|
Integer result = (Integer) conversionService.convert(foo,
|
||||||
|
new TypeDescriptor(getClass().getField("genericMap2")), TypeDescriptor.valueOf(Integer.class));
|
||||||
|
assertEquals(new Integer(1), result);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void genericConverterDelegatingBackToConversionServiceConverterNotFound() {
|
public void genericConverterDelegatingBackToConversionServiceConverterNotFound() {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue