Converter system implementation cleanup and tidying; wip
This commit is contained in:
parent
10c30f0315
commit
33c19b8b14
|
|
@ -51,19 +51,19 @@ public class SpelMapper implements Mapper<Object, Object> {
|
|||
this.autoMappingEnabled = autoMappingEnabled;
|
||||
}
|
||||
|
||||
public MappingConfiguration addMapping(String source, String target) {
|
||||
public MappingConfiguration addMapping(String sourceExpression, String targetExpression) {
|
||||
Expression sourceExp;
|
||||
try {
|
||||
sourceExp = expressionParser.parseExpression(source);
|
||||
sourceExp = expressionParser.parseExpression(sourceExpression);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The mapping source '" + source
|
||||
throw new IllegalArgumentException("The mapping source '" + sourceExpression
|
||||
+ "' is not a parseable value expression", e);
|
||||
}
|
||||
Expression targetExp;
|
||||
try {
|
||||
targetExp = expressionParser.parseExpression(target);
|
||||
targetExp = expressionParser.parseExpression(targetExpression);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException("The mapping target '" + source
|
||||
throw new IllegalArgumentException("The mapping target '" + sourceExpression
|
||||
+ "' is not a parseable property expression", e);
|
||||
}
|
||||
Mapping mapping = new Mapping(sourceExp, targetExp);
|
||||
|
|
@ -128,7 +128,7 @@ public class SpelMapper implements Mapper<Object, Object> {
|
|||
private boolean explicitlyMapped(String field) {
|
||||
for (Mapping mapping : mappings) {
|
||||
if (mapping.source.getExpressionString().equals(field)) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public class SpelMapperTests {
|
|||
private SpelMapper mapper = new SpelMapper();
|
||||
|
||||
@Test
|
||||
public void mapAutomatic() throws MappingException {
|
||||
public void mapAutomatic() {
|
||||
Map<String, Object> source = new HashMap<String, Object>();
|
||||
source.put("name", "Keith");
|
||||
source.put("age", 31);
|
||||
|
|
@ -45,7 +45,7 @@ public class SpelMapperTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void mapAutomaticWithExplictOverrides() throws MappingException {
|
||||
public void mapAutomaticWithExplictOverrides() {
|
||||
mapper.addMapping("test", "age");
|
||||
|
||||
Map<String, Object> source = new HashMap<String, Object>();
|
||||
|
|
@ -63,7 +63,7 @@ public class SpelMapperTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void mapSameSourceFieldToMultipleTargets() throws MappingException {
|
||||
public void mapSameSourceFieldToMultipleTargets() {
|
||||
mapper.addMapping("test", "name");
|
||||
mapper.addMapping("test", "favoriteSport");
|
||||
|
||||
|
|
@ -78,8 +78,36 @@ public class SpelMapperTests {
|
|||
assertEquals(0, target.age);
|
||||
assertEquals(Sport.FOOTBALL, target.favoriteSport);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bean() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class Employee {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Person {
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,9 @@ import org.springframework.util.ClassUtils;
|
|||
*/
|
||||
public class ConversionFailedException extends ConversionException {
|
||||
|
||||
private transient Object value;
|
||||
|
||||
private Class<?> sourceType;
|
||||
|
||||
private Class<?> targetType;
|
||||
|
||||
private TypeDescriptor targetType;
|
||||
|
||||
/**
|
||||
* Create a new conversion exception.
|
||||
|
|
@ -41,35 +38,12 @@ public class ConversionFailedException extends ConversionException {
|
|||
* @param targetType the value's target type
|
||||
* @param cause the cause of the conversion failure
|
||||
*/
|
||||
public ConversionFailedException(Object value, Class<?> sourceType, Class<?> targetType, Throwable cause) {
|
||||
public ConversionFailedException(Class<?> sourceType, TypeDescriptor targetType, Object value, Throwable cause) {
|
||||
super(buildDefaultMessage(value, sourceType, targetType, cause), cause);
|
||||
this.value = value;
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new conversion exception.
|
||||
* @param value the value we tried to convert
|
||||
* @param sourceType the value's original type
|
||||
* @param targetType the value's target type
|
||||
* @param message a descriptive message of what went wrong.
|
||||
*/
|
||||
public ConversionFailedException(Object value, Class<?> sourceType, Class<?> targetType, String message) {
|
||||
super(message);
|
||||
this.value = value;
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the actual value we tried to convert, an instance of {@link #getSourceType()}.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source type we tried to convert the value from.
|
||||
*/
|
||||
|
|
@ -80,15 +54,15 @@ public class ConversionFailedException extends ConversionException {
|
|||
/**
|
||||
* Returns the target type we tried to convert the value to.
|
||||
*/
|
||||
public Class<?> getTargetType() {
|
||||
public TypeDescriptor getTargetType() {
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
|
||||
private static String buildDefaultMessage(Object value, Class<?> sourceType, Class<?> targetType, Throwable cause) {
|
||||
private static String buildDefaultMessage(Object value, Class<?> sourceType, TypeDescriptor targetType, Throwable cause) {
|
||||
return "Unable to convert value " + StylerUtils.style(value) + " from type '" +
|
||||
ClassUtils.getQualifiedName(sourceType) + "' to type '" +
|
||||
ClassUtils.getQualifiedName(targetType) + "'; reason = '" + cause.getMessage() + "'";
|
||||
ClassUtils.getQualifiedName(targetType.getType()) + "'; reason = '" + cause.getMessage() + "'";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -28,15 +28,14 @@ public class ConverterNotFoundException extends ConversionException {
|
|||
|
||||
private final Class<?> targetType;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new conversion executor not found exception.
|
||||
* @param sourceType the source type requested to convert from
|
||||
* @param targetType the target type requested to convert to
|
||||
* @param message a descriptive message
|
||||
*/
|
||||
public ConverterNotFoundException(Class<?> sourceType, Class<?> targetType, String message) {
|
||||
super(message);
|
||||
public ConverterNotFoundException(Class<?> sourceType, Class<?> targetType) {
|
||||
super("No converter found capable of converting from [" + sourceType.getName() + "] to [" + targetType.getName() + "]");
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public class TypeDescriptor {
|
|||
|
||||
/**
|
||||
* Determine the declared (non-generic) type of the wrapped parameter/field.
|
||||
* @return the declared type (never <code>null</code>)
|
||||
* @return the declared type
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
if (this.type != null) {
|
||||
|
|
@ -128,6 +128,15 @@ public class TypeDescriptor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the declared type of the wrapped parameter/field.
|
||||
* Returns the Object wrapper type if the underlying type is a primitive.
|
||||
*/
|
||||
public Class getObjectType() {
|
||||
Class type = getType();
|
||||
return type != null ? ClassUtils.resolvePrimitiveIfNecessary(type) : type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this type; the fully qualified classname.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,103 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Base class for converters that convert to and from collection types (arrays and java.util.Collection types).
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
abstract class AbstractCollectionConverter implements ConversionExecutor {
|
||||
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private final TypeDescriptor sourceCollectionType;
|
||||
|
||||
private final TypeDescriptor targetCollectionType;
|
||||
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
public AbstractCollectionConverter(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, GenericConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
this.sourceCollectionType = sourceCollectionType;
|
||||
this.targetCollectionType = targetCollectionType;
|
||||
Class<?> sourceElementType = sourceCollectionType.getElementType();
|
||||
Class<?> targetElementType = targetCollectionType.getElementType();
|
||||
if (sourceElementType != null && targetElementType != null) {
|
||||
ConversionExecutor executor = conversionService.getConversionExecutor(sourceElementType, TypeDescriptor.valueOf(targetElementType));
|
||||
if (executor != null) {
|
||||
this.elementConverter = executor;
|
||||
}
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection type to convert to.
|
||||
*/
|
||||
protected Class<?> getTargetCollectionType() {
|
||||
return targetCollectionType.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of elements in the target collection.
|
||||
*/
|
||||
protected Class<?> getTargetElementType() {
|
||||
return this.targetCollectionType.getElementType();
|
||||
}
|
||||
|
||||
protected GenericConversionService getConversionService() {
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* The converter to use to convert elements to the {@link #getTargetElementType()}.
|
||||
* Returns {@link NoOpConversionExecutor#INSTANCE} if no converter could be eagerly resolved from type descriptor metadata.
|
||||
*/
|
||||
protected ConversionExecutor getElementConverter() {
|
||||
return this.elementConverter;
|
||||
}
|
||||
|
||||
|
||||
public Object execute(Object source) {
|
||||
try {
|
||||
return doExecute(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceCollectionType.getType(), this.targetCollectionType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to perform collection conversion.
|
||||
* @param sourceCollection the source collection to convert from, an instance of sourceCollectionType,
|
||||
* which must be either an array or java.util.Collection type.
|
||||
* @return the converted target collection, an instance of targetCollectionType
|
||||
* @throws Exception an exception occurred during the conversion
|
||||
*/
|
||||
protected abstract Object doExecute(Object sourceCollection) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +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 org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Special one-way converter that converts from a source array to a target array. Supports type conversion of the
|
||||
* individual array elements; for example, the ability to convert a String[] to an Integer[]. Mainly used internally by
|
||||
* {@link org.springframework.core.convert.ConversionService} implementations.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class ArrayToArray extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetArrayType, GenericConversionService conversionService) {
|
||||
super(sourceArrayType, targetArrayType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object doExecute(Object sourceArray) {
|
||||
int length = Array.getLength(sourceArray);
|
||||
Object targetArray = Array.newInstance(getTargetElementType(), length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object value = Array.get(sourceArray, i);
|
||||
Array.set(targetArray, i, getElementConverter().execute(value));
|
||||
}
|
||||
return targetArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +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.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* 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 parameterized target collection type descriptor is provided.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class ArrayToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToCollection(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType,
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceArrayType, targetCollectionType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doExecute(Object sourceArray) throws Exception {
|
||||
int length = Array.getLength(sourceArray);
|
||||
Collection collection = CollectionFactory.createCollection(getTargetCollectionType(), length);
|
||||
ConversionExecutor elementConverter = getElementConverter();
|
||||
for (int i = 0; i < length; i++) {
|
||||
collection.add(elementConverter.execute(Array.get(sourceArray, i)));
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,65 +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.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Special converter that converts from target collection to a source array.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class CollectionToArray extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToArray(TypeDescriptor sourceCollectionType, TypeDescriptor targetArrayType,
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceCollectionType, targetArrayType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doExecute(Object source) throws Exception {
|
||||
Collection<?> collection = (Collection<?>) source;
|
||||
Object array = Array.newInstance(getTargetElementType(), collection.size());
|
||||
int i = 0;
|
||||
ConversionExecutor elementConverter = getElementConverter(collection);
|
||||
for (Iterator<?> it = collection.iterator(); it.hasNext(); i++) {
|
||||
Array.set(array, i, elementConverter.execute(it.next()));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private ConversionExecutor getElementConverter(Collection<?> source) {
|
||||
ConversionExecutor elementConverter = getElementConverter();
|
||||
if (elementConverter == NoOpConversionExecutor.INSTANCE) {
|
||||
for (Object value : source) {
|
||||
if (value != null) {
|
||||
elementConverter = getConversionService()
|
||||
.getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (elementConverter != null ? elementConverter : NoOpConversionExecutor.INSTANCE);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,64 +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.util.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* A converter that can convert from one collection type to another.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CollectionToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToCollection(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType,
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceCollectionType, targetCollectionType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doExecute(Object source) throws Exception {
|
||||
Collection sourceCollection = (Collection) source;
|
||||
Collection targetCollection = CollectionFactory.createCollection(getTargetCollectionType(), sourceCollection.size());
|
||||
ConversionExecutor elementConverter = getElementConverter(sourceCollection);
|
||||
for (Object aSourceCollection : sourceCollection) {
|
||||
targetCollection.add(elementConverter.execute(aSourceCollection));
|
||||
}
|
||||
return targetCollection;
|
||||
}
|
||||
|
||||
private ConversionExecutor getElementConverter(Collection<?> source) {
|
||||
ConversionExecutor elementConverter = getElementConverter();
|
||||
if (elementConverter == NoOpConversionExecutor.INSTANCE && getTargetElementType() != null) {
|
||||
for (Object value : source) {
|
||||
if (value != null) {
|
||||
elementConverter = getConversionService().getConversionExecutor(
|
||||
value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return elementConverter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* A generic converter that can convert from one collection type to another.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class CollectionToCollectionGenericConverter implements GenericConverter {
|
||||
|
||||
private GenericConversionService conversionService;
|
||||
|
||||
public CollectionToCollectionGenericConverter(GenericConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public Object convert(Object source, TypeDescriptor targetType) {
|
||||
Collection sourceCollection = (Collection) source;
|
||||
Object firstNotNullElement = getFirstNotNullElement(sourceCollection);
|
||||
if (firstNotNullElement == null) {
|
||||
return compatibleCollectionWithoutElementConversion(sourceCollection, targetType);
|
||||
}
|
||||
Class targetElementType = targetType.getElementType();
|
||||
if (targetElementType == null || targetElementType.isAssignableFrom(firstNotNullElement.getClass())) {
|
||||
return compatibleCollectionWithoutElementConversion(sourceCollection, targetType);
|
||||
}
|
||||
Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
|
||||
GenericConverter elementConverter = conversionService.getConverter(firstNotNullElement.getClass(), targetElementType);
|
||||
for (Object element : sourceCollection) {
|
||||
targetCollection.add(elementConverter.convert(element, TypeDescriptor.valueOf(targetElementType)));
|
||||
}
|
||||
return targetCollection;
|
||||
}
|
||||
|
||||
private Collection compatibleCollectionWithoutElementConversion(Collection source, TypeDescriptor targetType) {
|
||||
if (targetType.getType().isAssignableFrom(source.getClass())) {
|
||||
return source;
|
||||
} else {
|
||||
Collection target = CollectionFactory.createCollection(targetType.getType(), source.size());
|
||||
for (Object element : source) {
|
||||
target.addAll(source);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getFirstNotNullElement(Collection collection) {
|
||||
for (Object element : collection) {
|
||||
if (element != null) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
|
||||
/**
|
||||
* A command parameterized with the information necessary to perform a conversion of a source input to a
|
||||
* target output. Encapsulates knowledge about how to convert source objects to a specific target type
|
||||
* using a specific converter.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
interface ConversionExecutor {
|
||||
|
||||
/**
|
||||
* Convert the source.
|
||||
* @param source the source to convert
|
||||
* @throws ConversionFailedException if an exception occurs during type conversion
|
||||
*/
|
||||
Object execute(Object source);
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of a conversion service. Will automatically register <i>from string</i>
|
||||
* converters for a number of standard Java types like Class, Number, Boolean and so on.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import java.lang.reflect.ParameterizedType;
|
|||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
|
@ -28,6 +29,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
|
@ -56,7 +58,11 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
* An indexed map of Converters. Each Map.Entry key is a source class (S) that can be converted from.
|
||||
* Each Map.Entry value is a Map that defines the targetType-to-Converter mappings for that source.
|
||||
*/
|
||||
private final Map<Class, Map<Class, Object>> sourceTypeConverters = new HashMap<Class, Map<Class, Object>>();
|
||||
private final Map<Class, Map<Class, GenericConverter>> sourceTypeConverters = new HashMap<Class, Map<Class, GenericConverter>>();
|
||||
|
||||
public GenericConversionService() {
|
||||
addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionGenericConverter(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the converters in the set provided.
|
||||
|
|
@ -95,25 +101,27 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
|
||||
// implementing ConverterRegistry
|
||||
|
||||
|
||||
public void addConverter(Converter converter) {
|
||||
List<Class> typeInfo = getRequiredTypeInfo(converter);
|
||||
if (typeInfo == null) {
|
||||
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> your Converter<S, T> converts between; declare these types or implement ConverterInfo");
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to the determine sourceType <S> and targetType <T> your Converter<S, T> converts between; declare these types or implement ConverterInfo");
|
||||
}
|
||||
Class sourceType = typeInfo.get(0);
|
||||
Class targetType = typeInfo.get(1);
|
||||
getSourceMap(sourceType).put(targetType, converter);
|
||||
getSourceMap(sourceType).put(targetType, new ConverterAdapter(converter));
|
||||
}
|
||||
|
||||
public void addConverterFactory(ConverterFactory<?, ?> converterFactory) {
|
||||
List<Class> typeInfo = getRequiredTypeInfo(converterFactory);
|
||||
if (typeInfo == null) {
|
||||
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> your ConverterFactory<S, T> creates Converters to convert between; declare these types or implement ConverterInfo");
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to the determine sourceType <S> and targetRangeType R your ConverterFactory<S, R> converts between; declare these types or implement ConverterInfo");
|
||||
}
|
||||
Class sourceType = typeInfo.get(0);
|
||||
Class targetType = typeInfo.get(1);
|
||||
getSourceMap(sourceType).put(targetType, converterFactory);
|
||||
getSourceMap(sourceType).put(targetType, new ConverterFactoryAdapter(converterFactory));
|
||||
}
|
||||
|
||||
public void removeConvertible(Class<?> sourceType, Class<?> targetType) {
|
||||
|
|
@ -128,178 +136,97 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) {
|
||||
ConversionExecutor executor = getConversionExecutor(sourceType, targetType);
|
||||
return (executor != null || (this.parent != null && this.parent.canConvert(sourceType, targetType)));
|
||||
Assert.notNull(sourceType, "The sourceType to convert from is required");
|
||||
Assert.notNull(targetType, "The targetType to convert to is required");
|
||||
if (targetType == TypeDescriptor.NULL) {
|
||||
return true;
|
||||
}
|
||||
Class sourceClass = ClassUtils.resolvePrimitiveIfNecessary(sourceType);
|
||||
Class targetClass = targetType.getObjectType();
|
||||
return getConverter(sourceClass, targetType.getObjectType()) != null || this.parent != null
|
||||
&& this.parent.canConvert(sourceClass, targetClass);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T convert(Object source, Class<T> targetType) {
|
||||
Assert.notNull(targetType, "The targetType to convert to is required");
|
||||
return (T) convert(source, TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public Object convert(Object source, TypeDescriptor targetType) {
|
||||
Assert.notNull(targetType, "The targetType to convert to is required");
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
ConversionExecutor executor = getConversionExecutor(source.getClass(), targetType);
|
||||
if (executor != null) {
|
||||
return executor.execute(source);
|
||||
if (targetType == TypeDescriptor.NULL) {
|
||||
return null;
|
||||
}
|
||||
else if (this.parent != null) {
|
||||
return this.parent.convert(source, targetType);
|
||||
}
|
||||
else {
|
||||
throw new ConverterNotFoundException(source.getClass(), targetType.getType(),
|
||||
"No converter found that can convert from source type [" + source.getClass().getName() +
|
||||
"] to target type [" + targetType.getName() + "]");
|
||||
Class sourceType = ClassUtils.resolvePrimitiveIfNecessary(source.getClass());
|
||||
GenericConverter converter = getConverter(sourceType, targetType.getObjectType());
|
||||
if (converter != null) {
|
||||
try {
|
||||
return converter.convert(source, targetType);
|
||||
} catch (ConversionFailedException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new ConversionFailedException(sourceType, targetType, source, e);
|
||||
}
|
||||
} else {
|
||||
if (targetType.isAssignableValue(source)) {
|
||||
return source;
|
||||
} else {
|
||||
throw new ConverterNotFoundException(sourceType, targetType.getObjectType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConversionExecutor getConversionExecutor(final Class<?> sourceClass, final TypeDescriptor targetType)
|
||||
throws ConverterNotFoundException {
|
||||
// subclassing hooks
|
||||
|
||||
Assert.notNull(sourceClass, "Source type to convert from is required");
|
||||
Assert.notNull(targetType, "Target type to convert to is required");
|
||||
if (targetType.getType() == null) {
|
||||
return NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
// TODO clean this if/else code up
|
||||
TypeDescriptor sourceType = TypeDescriptor.valueOf(sourceClass);
|
||||
if (sourceType.isArray()) {
|
||||
if (targetType.isArray()) {
|
||||
return new ArrayToArray(sourceType, targetType, this);
|
||||
}
|
||||
else if (targetType.isCollection()) {
|
||||
if (targetType.isAbstractClass()) {
|
||||
throw new IllegalArgumentException("Conversion target class [" + targetType.getName()
|
||||
+ "] is invalid; cannot convert to abstract collection types. "
|
||||
+ "Request an interface or a concrete implementation instead!");
|
||||
protected GenericConverter getConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
if (sourceType.isInterface()) {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, GenericConverter> converters = getConvertersForSource(currentClass);
|
||||
GenericConverter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
return new ArrayToCollection(sourceType, targetType, this);
|
||||
}
|
||||
else if (targetType.isMap()) {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
return new StringArrayToMap(sourceType, targetType, this);
|
||||
}
|
||||
else {
|
||||
// array to map
|
||||
return null;
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
return new StringArrayToObject(targetType, this);
|
||||
Map<Class, GenericConverter> objectConverters = getConvertersForSource(Object.class);
|
||||
return getConverter(objectConverters, targetType);
|
||||
} else {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, GenericConverter> converters = getConvertersForSource(currentClass);
|
||||
GenericConverter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
else {
|
||||
// array to object
|
||||
return null;
|
||||
if (currentClass.getSuperclass() != null) {
|
||||
classQueue.addFirst(currentClass.getSuperclass());
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sourceType.isCollection()) {
|
||||
if (targetType.isCollection()) {
|
||||
return new CollectionToCollection(sourceType, targetType, this);
|
||||
}
|
||||
else if (targetType.isArray()) {
|
||||
return new CollectionToArray(sourceType, targetType, this);
|
||||
}
|
||||
else if (targetType.isMap()) {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
return new StringCollectionToMap(sourceType, targetType, this);
|
||||
}
|
||||
else {
|
||||
// object collection to map
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (targetType.getType().equals(String.class)) {
|
||||
// collection to string
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
// collection to object
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sourceType.isMap()) {
|
||||
if (targetType.isMap()) {
|
||||
return new MapToMap(sourceType, targetType, this);
|
||||
}
|
||||
else if (targetType.isArray()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
return new MapToStringArray(targetType, this);
|
||||
}
|
||||
else {
|
||||
// map to object array
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (targetType.isCollection()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
return new MapToStringCollection(targetType, this);
|
||||
}
|
||||
else {
|
||||
// map to object collection
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// map to object
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (targetType.isArray()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToArray(targetType, this);
|
||||
}
|
||||
else {
|
||||
return new ObjectToArray(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isCollection()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToCollection(sourceType, targetType, this);
|
||||
}
|
||||
else {
|
||||
return new ObjectToCollection(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isMap()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToMap(sourceType, targetType, this);
|
||||
}
|
||||
else {
|
||||
// object to map
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (sourceType.isAssignableTo(targetType)) {
|
||||
return NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
Converter converter = findConverter(sourceClass, targetType);
|
||||
if (converter != null) {
|
||||
return new StaticConversionExecutor(sourceType, targetType, converter);
|
||||
}
|
||||
else if (this.parent instanceof GenericConversionService) {
|
||||
return ((GenericConversionService) this.parent).getConversionExecutor(sourceClass, targetType);
|
||||
}
|
||||
else if (this.parent != null && this.parent.canConvert(sourceClass, targetType)){
|
||||
return new ConversionExecutor() {
|
||||
public Object execute(Object source) {
|
||||
return parent.convert(source, targetType);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// internal helpers
|
||||
|
||||
private void addGenericConverter(Class<?> sourceType, Class<?> targetType, GenericConverter converter) {
|
||||
getSourceMap(sourceType).put(targetType, converter);
|
||||
}
|
||||
|
||||
private List<Class> getRequiredTypeInfo(Object converter) {
|
||||
List<Class> typeInfo = new ArrayList<Class>(2);
|
||||
if (converter instanceof ConverterInfo) {
|
||||
|
|
@ -307,8 +234,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
typeInfo.add(info.getSourceType());
|
||||
typeInfo.add(info.getTargetType());
|
||||
return typeInfo;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return getConverterTypeInfo(converter.getClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +255,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
if (arg1 instanceof Class) {
|
||||
typeInfo.add((Class) arg1);
|
||||
}
|
||||
}
|
||||
Type arg2 = paramIfc.getActualTypeArguments()[1];
|
||||
if (arg2 instanceof TypeVariable) {
|
||||
arg2 = GenericTypeResolver.resolveTypeVariable((TypeVariable) arg2, converterClass);
|
||||
|
|
@ -339,13 +265,11 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
if (typeInfo.size() == 2) {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
else if (Converter.class.isAssignableFrom((Class) rawType)) {
|
||||
}
|
||||
} else if (Converter.class.isAssignableFrom((Class) rawType)) {
|
||||
return getConverterTypeInfo((Class) rawType);
|
||||
}
|
||||
}
|
||||
else if (Converter.class.isAssignableFrom((Class) ifc)) {
|
||||
} else if (Converter.class.isAssignableFrom((Class) ifc)) {
|
||||
return getConverterTypeInfo((Class) ifc);
|
||||
}
|
||||
}
|
||||
|
|
@ -353,78 +277,31 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<Class, Object> getSourceMap(Class sourceType) {
|
||||
Map<Class, Object> sourceMap = sourceTypeConverters.get(sourceType);
|
||||
|
||||
private Map<Class, GenericConverter> getSourceMap(Class sourceType) {
|
||||
Map<Class, GenericConverter> sourceMap = sourceTypeConverters.get(sourceType);
|
||||
if (sourceMap == null) {
|
||||
sourceMap = new HashMap<Class, Object>();
|
||||
sourceMap = new HashMap<Class, GenericConverter>();
|
||||
sourceTypeConverters.put(sourceType, sourceMap);
|
||||
}
|
||||
return sourceMap;
|
||||
}
|
||||
|
||||
protected Converter findConverter(Class<?> sourceType, TypeDescriptor targetType) {
|
||||
return findRegisteredConverter(
|
||||
ClassUtils.resolvePrimitiveIfNecessary(sourceType),
|
||||
ClassUtils.resolvePrimitiveIfNecessary(targetType.getType()));
|
||||
}
|
||||
|
||||
private Converter findRegisteredConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
if (sourceType.isInterface()) {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, Object> converters = getConvertersForSource(currentClass);
|
||||
Converter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
Map<Class, Object> objectConverters = getConvertersForSource(Object.class);
|
||||
return getConverter(objectConverters, targetType);
|
||||
}
|
||||
else {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, Object> converters = getConvertersForSource(currentClass);
|
||||
Converter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
if (currentClass.getSuperclass() != null) {
|
||||
classQueue.addFirst(currentClass.getSuperclass());
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Class, Object> getConvertersForSource(Class<?> sourceType) {
|
||||
Map<Class, Object> converters = this.sourceTypeConverters.get(sourceType);
|
||||
private Map<Class, GenericConverter> getConvertersForSource(Class<?> sourceType) {
|
||||
Map<Class, GenericConverter> converters = this.sourceTypeConverters.get(sourceType);
|
||||
if (converters == null) {
|
||||
converters = Collections.emptyMap();
|
||||
}
|
||||
return converters;
|
||||
}
|
||||
|
||||
private Converter getConverter(Map<Class, Object> converters, Class<?> targetType) {
|
||||
private GenericConverter getConverter(Map<Class, GenericConverter> converters, Class<?> targetType) {
|
||||
if (targetType.isInterface()) {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(targetType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Converter converter = getConverter(converters, currentClass, targetType);
|
||||
GenericConverter converter = converters.get(currentClass);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
|
|
@ -433,14 +310,13 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
return getConverter(converters, Object.class, targetType);
|
||||
}
|
||||
else {
|
||||
return converters.get(Object.class);
|
||||
} else {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(targetType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Converter converter = getConverter(converters, currentClass, targetType);
|
||||
GenericConverter converter = converters.get(currentClass);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
|
|
@ -453,20 +329,35 @@ public class GenericConversionService implements ConversionService, ConverterReg
|
|||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Converter getConverter(Map<Class, Object> converters, Class<?> currentClass, Class<?> targetType) {
|
||||
Object converter = converters.get(currentClass);
|
||||
if (converter == null) {
|
||||
return null;
|
||||
static class ConverterAdapter implements GenericConverter {
|
||||
|
||||
private Converter converter;
|
||||
|
||||
public ConverterAdapter(Converter converter) {
|
||||
this.converter = converter;
|
||||
}
|
||||
if (converter instanceof Converter) {
|
||||
return (Converter) converter;
|
||||
|
||||
public Object convert(Object source, TypeDescriptor type) {
|
||||
return converter.convert(source);
|
||||
}
|
||||
else {
|
||||
return ((ConverterFactory) converter).getConverter(targetType);
|
||||
|
||||
}
|
||||
|
||||
static class ConverterFactoryAdapter implements GenericConverter {
|
||||
|
||||
private ConverterFactory converterFactory;
|
||||
|
||||
public ConverterFactoryAdapter(ConverterFactory converterFactory) {
|
||||
this.converterFactory = converterFactory;
|
||||
}
|
||||
|
||||
public Object convert(Object source, TypeDescriptor targetType) {
|
||||
return converterFactory.getConverter(targetType.getObjectType()).convert(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package org.springframework.core.convert.support;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
interface GenericConverter {
|
||||
|
||||
Object convert(Object source, TypeDescriptor type);
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +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;
|
||||
|
||||
/**
|
||||
* A helper for convertering map keys and values.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class MapEntryConverter {
|
||||
|
||||
public static final MapEntryConverter NO_OP_INSTANCE = new MapEntryConverter(null, null);
|
||||
|
||||
private final ConversionExecutor keyConverter;
|
||||
|
||||
private final ConversionExecutor valueConverter;
|
||||
|
||||
public MapEntryConverter(ConversionExecutor keyConverter, ConversionExecutor valueConverter) {
|
||||
this.keyConverter = keyConverter;
|
||||
this.valueConverter = valueConverter;
|
||||
}
|
||||
|
||||
public Object convertKey(Object key) {
|
||||
if (this.keyConverter != null) {
|
||||
return this.keyConverter.execute(key);
|
||||
}
|
||||
else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertValue(Object value) {
|
||||
if (this.valueConverter != null) {
|
||||
return this.valueConverter.execute(value);
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,113 +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.util.Map;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts from one map to another map, with support for converting individual map elements
|
||||
* based on generic type information.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class MapToMap implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor sourceType;
|
||||
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
/**
|
||||
* Creates a new map-to-map converter
|
||||
* @param sourceType the source map type
|
||||
* @param targetType the target map type
|
||||
* @param conversionService the conversion service
|
||||
*/
|
||||
public MapToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (this.sourceType.isMapEntryTypeKnown() && this.targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = this.conversionService.getConversionExecutor(
|
||||
this.sourceType.getMapKeyType(), TypeDescriptor.valueOf(this.targetType.getMapKeyType()));
|
||||
ConversionExecutor valueConverter = this.conversionService.getConversionExecutor(
|
||||
this.sourceType.getMapValueType(), TypeDescriptor.valueOf(this.targetType.getMapValueType()));
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
Map<?, ?> map = (Map<?, ?>) source;
|
||||
Map targetMap = CollectionFactory.createMap(this.targetType.getType(), map.size());
|
||||
MapEntryConverter converter = getEntryConverter(map);
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
targetMap.put(converter.convertKey(entry.getKey()), converter.convertValue(entry.getValue()));
|
||||
}
|
||||
return targetMap;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private MapEntryConverter getEntryConverter(Map<?, ?> map) {
|
||||
MapEntryConverter entryConverter = this.entryConverter;
|
||||
if (entryConverter == MapEntryConverter.NO_OP_INSTANCE) {
|
||||
Class<?> targetKeyType = targetType.getMapKeyType();
|
||||
Class<?> targetValueType = targetType.getMapValueType();
|
||||
if (targetKeyType != null && targetValueType != null) {
|
||||
ConversionExecutor keyConverter = null;
|
||||
ConversionExecutor valueConverter = null;
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (keyConverter == null && key != null) {
|
||||
keyConverter = conversionService
|
||||
.getConversionExecutor(key.getClass(), TypeDescriptor.valueOf(targetKeyType));
|
||||
}
|
||||
if (valueConverter == null && value != null) {
|
||||
valueConverter = conversionService
|
||||
.getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(targetValueType));
|
||||
}
|
||||
if (keyConverter != null && valueConverter != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
entryConverter = new MapEntryConverter(keyConverter, valueConverter);
|
||||
}
|
||||
}
|
||||
return entryConverter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,74 +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.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a Map to a String array, where each element in the array
|
||||
* is of the format key=value.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class MapToStringArray implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
public MapToStringArray(TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (this.targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = this.conversionService.getConversionExecutor(this.targetType.getMapKeyType(),
|
||||
TypeDescriptor.valueOf(String.class));
|
||||
ConversionExecutor valueConverter = this.conversionService.getConversionExecutor(this.targetType.getMapValueType(),
|
||||
TypeDescriptor.valueOf(String.class));
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Map sourceMap = (Map) source;
|
||||
Object array = Array.newInstance(this.targetType.getElementType(), sourceMap.size());
|
||||
int i = 0;
|
||||
for (Object entry : sourceMap.entrySet()) {
|
||||
Map.Entry mapEntry = (Map.Entry) entry;
|
||||
Object key = mapEntry.getKey();
|
||||
Object value = mapEntry.getValue();
|
||||
String property = this.entryConverter.convertKey(key) + "=" + this.entryConverter.convertValue(value);
|
||||
Array.set(array, i, property);
|
||||
i++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +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.util.Map;
|
||||
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a Map to a String collection, where each element in the collection
|
||||
* is of the format key=value.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class MapToStringCollection implements ConversionExecutor {
|
||||
|
||||
private final MapToStringArray converter;
|
||||
|
||||
private final ArrayToCollection collectionConverter;
|
||||
|
||||
public MapToStringCollection(TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.converter = new MapToStringArray(targetType, conversionService);
|
||||
this.collectionConverter = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), targetType, conversionService);
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Map map = (Map) source;
|
||||
Object array = this.converter.execute(map);
|
||||
return this.collectionConverter.execute(array);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
|
||||
/**
|
||||
* Conversion executor that does nothing.
|
||||
* Access singleton using {@link #INSTANCE}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class NoOpConversionExecutor implements ConversionExecutor {
|
||||
|
||||
public static final ConversionExecutor INSTANCE = new NoOpConversionExecutor();
|
||||
|
||||
private NoOpConversionExecutor() {
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
// does nothing
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,51 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts an object to a single-element array.
|
||||
* TODO - this class throws cryptic exception if it can't convert to required target array element type.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class ObjectToArray implements ConversionExecutor {
|
||||
|
||||
private final Class elementType;
|
||||
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
public ObjectToArray(TypeDescriptor sourceObjectType, TypeDescriptor targetArrayType,
|
||||
GenericConversionService conversionService) {
|
||||
this.elementType = targetArrayType.getElementType();
|
||||
this.elementConverter = conversionService.getConversionExecutor(
|
||||
sourceObjectType.getType(), TypeDescriptor.valueOf(this.elementType));
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Object array = Array.newInstance(this.elementType, 1);
|
||||
Object element = this.elementConverter.execute(source);
|
||||
Array.set(array, 0, element);
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,55 +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.util.Collection;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts an object to a single-element collection.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class ObjectToCollection implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor targetCollectionType;
|
||||
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
public ObjectToCollection(TypeDescriptor sourceObjectType, TypeDescriptor targetCollectionType,
|
||||
GenericConversionService typeConverter) {
|
||||
this.targetCollectionType = targetCollectionType;
|
||||
Class<?> elementType = targetCollectionType.getElementType();
|
||||
if (elementType != null) {
|
||||
this.elementConverter = typeConverter.getConversionExecutor(sourceObjectType.getType(), TypeDescriptor.valueOf(elementType));
|
||||
}
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Collection collection = CollectionFactory.createCollection(this.targetCollectionType.getType(), 1);
|
||||
collection.add(this.elementConverter.execute(source));
|
||||
return collection;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
* Default conversion executor implementation for converters.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class StaticConversionExecutor implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor sourceType;
|
||||
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private final Converter converter;
|
||||
|
||||
public StaticConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType, Converter converter) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
if (!this.sourceType.isAssignableValue(source)) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(),
|
||||
"Source object " + source + " to convert is expected to be an instance of [" + this.sourceType.getName() + "]");
|
||||
}
|
||||
try {
|
||||
return this.converter.convert(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof StaticConversionExecutor)) {
|
||||
return false;
|
||||
}
|
||||
StaticConversionExecutor other = (StaticConversionExecutor) obj;
|
||||
return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.sourceType.hashCode() + this.targetType.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a String array to a Map.
|
||||
* Each element in the array must be formatted as key=value.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class StringArrayToMap implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor sourceType;
|
||||
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
public StringArrayToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (this.targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = this.conversionService.getConversionExecutor(String.class,
|
||||
TypeDescriptor.valueOf(this.targetType.getMapKeyType()));
|
||||
ConversionExecutor valueConverter = this.conversionService.getConversionExecutor(String.class,
|
||||
TypeDescriptor.valueOf(this.targetType.getMapValueType()));
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
int length = Array.getLength(source);
|
||||
Map targetMap = CollectionFactory.createMap(this.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);
|
||||
}
|
||||
String key = fields[0];
|
||||
String value = fields[1];
|
||||
targetMap.put(this.entryConverter.convertKey(key), this.entryConverter.convertValue(value));
|
||||
}
|
||||
return targetMap;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Converts a String array to a single element.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class StringArrayToObject implements ConversionExecutor {
|
||||
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
public StringArrayToObject(TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.elementConverter = conversionService.getConversionExecutor(String.class, targetType);
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
String str = StringUtils.arrayToCommaDelimitedString(ObjectUtils.toObjectArray(source));
|
||||
return this.elementConverter.execute(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +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.util.Collection;
|
||||
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a String collection to a Map.
|
||||
* Each element in the collection must be formatted as key=value.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StringCollectionToMap implements ConversionExecutor {
|
||||
|
||||
private StringArrayToMap converter;
|
||||
|
||||
public StringCollectionToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new StringArrayToMap(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Collection collection = (Collection) source;
|
||||
return converter.execute(collection.toArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,43 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a comma-delimited string to a collection.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StringToCollection implements ConversionExecutor {
|
||||
|
||||
private final ArrayToCollection converter;
|
||||
|
||||
public StringToCollection(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.converter = new ArrayToCollection(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
String string = (String) source;
|
||||
String[] fields = string.split(",");
|
||||
return this.converter.execute(fields);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +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 org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a String to a map.
|
||||
* The String should be in the format:
|
||||
* <pre>
|
||||
* key=value
|
||||
* key=value
|
||||
* key=value
|
||||
* key=value
|
||||
* </pre>
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
class StringToMap implements ConversionExecutor {
|
||||
|
||||
private StringArrayToMap converter;
|
||||
|
||||
public StringToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new StringArrayToMap(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
String string = (String) source;
|
||||
String[] entries = string.split(" ");
|
||||
return converter.execute(entries);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +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.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ArrayToArrayTests {
|
||||
|
||||
@Test
|
||||
public void testArrayToArrayConversion() {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToArray c = new ArrayToArray(TypeDescriptor.valueOf(String[].class), TypeDescriptor.valueOf(Integer[].class), service);
|
||||
Integer[] result = (Integer[]) c.execute(new String[] { "1", "2", "3" });
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
assertEquals(new Integer(2), result[1]);
|
||||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,85 +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.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ArrayToCollectionTests {
|
||||
|
||||
@Test
|
||||
public void testArrayToCollectionConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("bindTarget")), service);
|
||||
Collection result = (Collection) c.execute(new String[] { "1", "2", "3" });
|
||||
assertEquals(3, result.size());
|
||||
assertTrue(result.contains(1));
|
||||
assertTrue(result.contains(2));
|
||||
assertTrue(result.contains(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayToSetConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("setTarget")), service);
|
||||
Set result = (Set) c.execute(new String[] { "1" });
|
||||
assertEquals("1", result.iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayToSortedSetConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("sortedSetTarget")), service);
|
||||
SortedSet result = (SortedSet) c.execute(new String[] { "1" });
|
||||
assertEquals(new Integer(1), result.iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayToCollectionImplConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("implTarget")), service);
|
||||
LinkedList result = (LinkedList) c.execute(new String[] { "1" });
|
||||
assertEquals("1", result.iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayToNonGenericCollectionConversionNullElement() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("listTarget")), service);
|
||||
List result = (List) c.execute(new Integer[] { null, new Integer(1) });
|
||||
assertEquals(null, result.get(0));
|
||||
assertEquals(new Integer(1), result.get(1));
|
||||
}
|
||||
|
||||
public Collection<Integer> bindTarget;
|
||||
public List listTarget;
|
||||
public Set setTarget;
|
||||
public SortedSet<Integer> sortedSetTarget;
|
||||
public LinkedList<String> implTarget;
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CollectionToArrayTests {
|
||||
|
||||
@Test
|
||||
public void testCollectionToArrayConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(new TypeDescriptor(getClass().getField("bindTarget")),
|
||||
TypeDescriptor.valueOf(Integer[].class), service);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Integer[] result = (Integer[]) c.execute(bindTarget);
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
assertEquals(new Integer(2), result[1]);
|
||||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToArrayConversionNoGenericInfo() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
|
||||
.valueOf(Integer[].class), service);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Integer[] result = (Integer[]) c.execute(bindTarget);
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
assertEquals(new Integer(2), result[1]);
|
||||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToArrayConversionNoGenericInfoNullElement() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
|
||||
.valueOf(Integer[].class), service);
|
||||
bindTarget.add(null);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Integer[] result = (Integer[]) c.execute(bindTarget);
|
||||
assertEquals(null, result[0]);
|
||||
assertEquals(new Integer(1), result[1]);
|
||||
assertEquals(new Integer(2), result[2]);
|
||||
assertEquals(new Integer(3), result[3]);
|
||||
}
|
||||
|
||||
public Collection<String> bindTarget = new ArrayList<String>();
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,109 +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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CollectionToCollectionTests {
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversion() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(new TypeDescriptor(getClass().getField("bindTarget")),
|
||||
new TypeDescriptor(getClass().getField("integerTarget")), service);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
assertEquals(3, result.size());
|
||||
assertTrue(result.contains(1));
|
||||
assertTrue(result.contains(2));
|
||||
assertTrue(result.contains(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversionNoGenericInfo() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(TypeDescriptor.valueOf(Collection.class),
|
||||
TypeDescriptor.valueOf(List.class), service);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
assertEquals(3, result.size());
|
||||
assertTrue(result.contains("1"));
|
||||
assertTrue(result.contains("2"));
|
||||
assertTrue(result.contains("3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversionNoGenericInfoSource() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(TypeDescriptor.valueOf(Collection.class),
|
||||
new TypeDescriptor(getClass().getField("integerTarget")), service);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
assertEquals(3, result.size());
|
||||
assertTrue(result.contains(1));
|
||||
assertTrue(result.contains(2));
|
||||
assertTrue(result.contains(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversionNoGenericInfoSourceNullValue() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(TypeDescriptor.valueOf(Collection.class),
|
||||
new TypeDescriptor(getClass().getField("integerTarget")), service);
|
||||
bindTarget.add(null);
|
||||
bindTarget.add("1");
|
||||
bindTarget.add("2");
|
||||
bindTarget.add("3");
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
Iterator it = result.iterator();
|
||||
assertEquals(null, it.next());
|
||||
assertEquals(new Integer(1), it.next());
|
||||
assertEquals(new Integer(2), it.next());
|
||||
assertEquals(new Integer(3), it.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversionNoGenericInfoSourceEmpty() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(TypeDescriptor.valueOf(Collection.class),
|
||||
new TypeDescriptor(getClass().getField("integerTarget")), service);
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
public Collection<String> bindTarget = new ArrayList<String>();
|
||||
public List<Integer> integerTarget = new ArrayList<Integer>();
|
||||
|
||||
}
|
||||
|
|
@ -25,21 +25,6 @@ import java.util.Locale;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.NumberToCharacter;
|
||||
import org.springframework.core.convert.support.NumberToNumberFactory;
|
||||
import org.springframework.core.convert.support.ObjectToString;
|
||||
import org.springframework.core.convert.support.StringToBigDecimal;
|
||||
import org.springframework.core.convert.support.StringToBigInteger;
|
||||
import org.springframework.core.convert.support.StringToBoolean;
|
||||
import org.springframework.core.convert.support.StringToByte;
|
||||
import org.springframework.core.convert.support.StringToCharacter;
|
||||
import org.springframework.core.convert.support.StringToDouble;
|
||||
import org.springframework.core.convert.support.StringToEnumFactory;
|
||||
import org.springframework.core.convert.support.StringToFloat;
|
||||
import org.springframework.core.convert.support.StringToInteger;
|
||||
import org.springframework.core.convert.support.StringToLocale;
|
||||
import org.springframework.core.convert.support.StringToLong;
|
||||
import org.springframework.core.convert.support.StringToShort;
|
||||
|
||||
/**
|
||||
* Tests for the default converters in the converters package.
|
||||
|
|
@ -48,70 +33,64 @@ import org.springframework.core.convert.support.StringToShort;
|
|||
*/
|
||||
public class DefaultConversionServiceTests {
|
||||
|
||||
@Test
|
||||
public void testStringToByte() throws Exception {
|
||||
StringToByte b = new StringToByte();
|
||||
assertEquals(Byte.valueOf("1"), b.convert("1"));
|
||||
}
|
||||
|
||||
private StringToNumberConverterFactory c = new StringToNumberConverterFactory();
|
||||
|
||||
@Test
|
||||
public void testStringToCharacter() {
|
||||
StringToCharacter c = new StringToCharacter();
|
||||
StringToCharacterConverter c = new StringToCharacterConverter();
|
||||
assertEquals(Character.valueOf('1'), c.convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToBoolean() {
|
||||
StringToBoolean c = new StringToBoolean();
|
||||
StringToBooleanConverter c = new StringToBooleanConverter();
|
||||
assertEquals(Boolean.valueOf(true), c.convert("true"));
|
||||
assertEquals(Boolean.valueOf(false), c.convert("false"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testStringToByte() throws Exception {
|
||||
assertEquals(Byte.valueOf("1"), c.getConverter(Byte.class).convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToShort() {
|
||||
StringToShort c = new StringToShort();
|
||||
assertEquals(Short.valueOf("1"), c.convert("1"));
|
||||
assertEquals(Short.valueOf("1"), c.getConverter(Short.class).convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToInteger() {
|
||||
StringToInteger c = new StringToInteger();
|
||||
assertEquals(Integer.valueOf("1"), c.convert("1"));
|
||||
assertEquals(Integer.valueOf("1"), c.getConverter(Integer.class).convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToLong() {
|
||||
StringToLong c = new StringToLong();
|
||||
assertEquals(Long.valueOf("1"), c.convert("1"));
|
||||
assertEquals(Long.valueOf("1"), c.getConverter(Long.class).convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToFloat() {
|
||||
StringToFloat c = new StringToFloat();
|
||||
assertEquals(Float.valueOf("1.0"), c.convert("1.0"));
|
||||
assertEquals(Float.valueOf("1.0"), c.getConverter(Float.class).convert("1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToDouble() {
|
||||
StringToDouble c = new StringToDouble();
|
||||
assertEquals(Double.valueOf("1.0"), c.convert("1.0"));
|
||||
assertEquals(Double.valueOf("1.0"), c.getConverter(Double.class).convert("1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToBigInteger() {
|
||||
StringToBigInteger c = new StringToBigInteger();
|
||||
assertEquals(new BigInteger("1"), c.convert("1"));
|
||||
assertEquals(new BigInteger("1"), c.getConverter(BigInteger.class).convert("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToBigDouble() {
|
||||
StringToBigDecimal c = new StringToBigDecimal();
|
||||
assertEquals(new BigDecimal("1.0"), c.convert("1.0"));
|
||||
assertEquals(new BigDecimal("1.0"), c.getConverter(BigDecimal.class).convert("1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringToEnum() throws Exception {
|
||||
Converter<String, Foo> c = new StringToEnumFactory().getConverter(Foo.class);
|
||||
Converter<String, Foo> c = new StringToEnumConverterFactory().getConverter(Foo.class);
|
||||
assertEquals(Foo.BAR, c.convert("BAR"));
|
||||
}
|
||||
|
||||
|
|
@ -121,19 +100,19 @@ public class DefaultConversionServiceTests {
|
|||
|
||||
@Test
|
||||
public void testStringToLocale() {
|
||||
StringToLocale c = new StringToLocale();
|
||||
StringToLocaleConverter c = new StringToLocaleConverter();
|
||||
assertEquals(Locale.ENGLISH, c.convert("en"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumberToNumber() throws Exception {
|
||||
Converter<Number, Long> c = new NumberToNumberFactory().getConverter(Long.class);
|
||||
Converter<Number, Long> c = new NumberToNumberConverterFactory().getConverter(Long.class);
|
||||
assertEquals(Long.valueOf(1), c.convert(Integer.valueOf(1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumberToNumberNotSupportedNumber() throws Exception {
|
||||
Converter<Number, CustomNumber> c = new NumberToNumberFactory().getConverter(CustomNumber.class);
|
||||
Converter<Number, CustomNumber> c = new NumberToNumberConverterFactory().getConverter(CustomNumber.class);
|
||||
try {
|
||||
c.convert(Integer.valueOf(1));
|
||||
fail("Should have failed");
|
||||
|
|
@ -144,13 +123,13 @@ public class DefaultConversionServiceTests {
|
|||
|
||||
@Test
|
||||
public void testNumberToCharacter() {
|
||||
NumberToCharacter n = new NumberToCharacter();
|
||||
NumberToCharacterConverter n = new NumberToCharacterConverter();
|
||||
assertEquals(Character.valueOf('A'), n.convert(Integer.valueOf(65)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectToString() {
|
||||
ObjectToString o = new ObjectToString();
|
||||
ObjectToStringConverter o = new ObjectToStringConverter();
|
||||
assertEquals("3", o.convert(3));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,13 @@ import static junit.framework.Assert.fail;
|
|||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
|
|
@ -42,7 +45,7 @@ public class GenericConversionServiceTests {
|
|||
|
||||
@Test
|
||||
public void executeConversion() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
assertEquals(new Integer(3), converter.convert("3", Integer.class));
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +72,7 @@ public class GenericConversionServiceTests {
|
|||
public void addConverterNoSourceTargetClassInfoAvailable() {
|
||||
try {
|
||||
converter.addConverter(new Converter() {
|
||||
public Object convert(Object source) throws Exception {
|
||||
public Object convert(Object source) {
|
||||
return source;
|
||||
}
|
||||
});
|
||||
|
|
@ -84,20 +87,20 @@ public class GenericConversionServiceTests {
|
|||
assertNull(converter.convert(null, Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void convertNullTargetClass() {
|
||||
assertEquals("3", converter.convert("3", (Class<?>)null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertNullConversionPointType() {
|
||||
assertEquals("3", converter.convert("3", TypeDescriptor.NULL));
|
||||
assertEquals(null, converter.convert("3", TypeDescriptor.NULL));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void convertWrongTypeArgument() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
try {
|
||||
converter.convert("BOGUS", Integer.class);
|
||||
fail("Should have failed");
|
||||
|
|
@ -109,7 +112,7 @@ public class GenericConversionServiceTests {
|
|||
@Test
|
||||
public void convertSuperSourceType() {
|
||||
converter.addConverter(new Converter<CharSequence, Integer>() {
|
||||
public Integer convert(CharSequence source) throws Exception {
|
||||
public Integer convert(CharSequence source) {
|
||||
return Integer.valueOf(source.toString());
|
||||
}
|
||||
});
|
||||
|
|
@ -119,14 +122,15 @@ public class GenericConversionServiceTests {
|
|||
|
||||
@Test
|
||||
public void convertObjectToPrimitive() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
Integer three = converter.convert("3", int.class);
|
||||
assertEquals(3, three.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToArray() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
Integer[] result = converter.convert(new String[] { "1", "2", "3" }, Integer[].class);
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
assertEquals(new Integer(2), result[1]);
|
||||
|
|
@ -134,8 +138,9 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToPrimitiveArray() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
int[] result = converter.convert(new String[] { "1", "2", "3" }, int[].class);
|
||||
assertEquals(1, result[0]);
|
||||
assertEquals(2, result[1]);
|
||||
|
|
@ -143,6 +148,7 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToListInterface() {
|
||||
List<?> result = converter.convert(new String[] { "1", "2", "3" }, List.class);
|
||||
assertEquals("1", result.get(0));
|
||||
|
|
@ -153,8 +159,9 @@ public class GenericConversionServiceTests {
|
|||
public List<Integer> genericList = new ArrayList<Integer>();
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToListGenericTypeConversion() throws Exception {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
List<Integer> result = (List<Integer>) converter.convert(new String[] { "1", "2", "3" }, new TypeDescriptor(getClass().getDeclaredField("genericList")));
|
||||
assertEquals(new Integer("1"), result.get(0));
|
||||
assertEquals(new Integer("2"), result.get(1));
|
||||
|
|
@ -162,6 +169,7 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToListImpl() {
|
||||
LinkedList<?> result = converter.convert(new String[] { "1", "2", "3" }, LinkedList.class);
|
||||
assertEquals("1", result.get(0));
|
||||
|
|
@ -170,6 +178,7 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertArrayToAbstractList() {
|
||||
try {
|
||||
converter.convert(new String[] { "1", "2", "3" }, AbstractList.class);
|
||||
|
|
@ -179,6 +188,7 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertListToArray() {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("1");
|
||||
|
|
@ -191,8 +201,9 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertListToArrayWithComponentConversion() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("1");
|
||||
list.add("2");
|
||||
|
|
@ -203,21 +214,36 @@ public class GenericConversionServiceTests {
|
|||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertCollectionToCollection() throws Exception {
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
Set<String> foo = new LinkedHashSet<String>();
|
||||
foo.add("1");
|
||||
foo.add("2");
|
||||
foo.add("3");
|
||||
List<Integer> bar = (List<Integer>)converter.convert(foo, new TypeDescriptor(getClass().getField("genericList")));
|
||||
assertEquals(new Integer(1), bar.get(0));
|
||||
assertEquals(new Integer(2), bar.get(1));
|
||||
assertEquals(new Integer(3), bar.get(2));
|
||||
}
|
||||
|
||||
public Map<Integer, FooEnum> genericMap = new HashMap<Integer, FooEnum>();
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertMapToMap() throws Exception {
|
||||
Map<String, String> foo = new HashMap<String, String>();
|
||||
foo.put("1", "BAR");
|
||||
foo.put("2", "BAZ");
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverter(new StringToEnumFactory().getConverter(FooEnum.class));
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
converter.addConverterFactory(new StringToEnumConverterFactory());
|
||||
Map<String, FooEnum> map = (Map<String, FooEnum>) converter.convert(foo, new TypeDescriptor(getClass().getField("genericMap")));
|
||||
assertEquals(map.get(1), FooEnum.BAR);
|
||||
assertEquals(map.get(2), FooEnum.BAZ);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertStringToArray() {
|
||||
String[] result = (String[]) converter.convert("1,2,3", String[].class);
|
||||
assertEquals(3, result.length);
|
||||
|
|
@ -227,8 +253,9 @@ public class GenericConversionServiceTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void convertStringToArrayWithElementConversion() {
|
||||
converter.addConverter(new StringToInteger());
|
||||
converter.addConverterFactory(new StringToNumberConverterFactory());
|
||||
Integer[] result = converter.convert("1,2,3", Integer[].class);
|
||||
assertEquals(3, result.length);
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
|
|
@ -238,7 +265,6 @@ public class GenericConversionServiceTests {
|
|||
|
||||
|
||||
public static enum FooEnum {
|
||||
|
||||
BAR, BAZ
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,78 +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.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.MapToMap;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class MapToMapTests {
|
||||
|
||||
@Test
|
||||
public void testMapToMapConversion() throws Exception {
|
||||
DefaultConversionService converter = new DefaultConversionService();
|
||||
MapToMap c = new MapToMap(new TypeDescriptor(getClass().getField("source")),
|
||||
new TypeDescriptor(getClass().getField("bindTarget")), converter);
|
||||
source.put("1", "BAR");
|
||||
source.put("2", "BAZ");
|
||||
Map<String, FooEnum> result = (Map<String, FooEnum>) c.execute(source);
|
||||
assertEquals(FooEnum.BAR, result.get(1));
|
||||
assertEquals(FooEnum.BAZ, result.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapToMapConversionNoGenericInfoOnSource() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
MapToMap c = new MapToMap(TypeDescriptor.valueOf(Map.class),
|
||||
new TypeDescriptor(getClass().getField("bindTarget")), service);
|
||||
source.put("1", "BAR");
|
||||
source.put("2", "BAZ");
|
||||
Map result = (Map) c.execute(source);
|
||||
assertEquals(FooEnum.BAR, result.get(1));
|
||||
assertEquals(FooEnum.BAZ, result.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapToMapConversionNoGenericInfo() throws Exception {
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
MapToMap c = new MapToMap(TypeDescriptor.valueOf(Map.class),
|
||||
TypeDescriptor.valueOf(Map.class), service);
|
||||
source.put("1", "BAR");
|
||||
source.put("2", "BAZ");
|
||||
Map result = (Map) c.execute(source);
|
||||
assertEquals("BAR", result.get("1"));
|
||||
assertEquals("BAZ", result.get("2"));
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> source = new HashMap<String, String>();
|
||||
public Map<Integer, FooEnum> bindTarget = new HashMap<Integer, FooEnum>();
|
||||
|
||||
public static enum FooEnum {
|
||||
BAR, BAZ;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue