Converter system implementation cleanup and tidying; wip

This commit is contained in:
Keith Donald 2009-09-17 19:24:07 +00:00
parent 10c30f0315
commit 33c19b8b14
35 changed files with 325 additions and 1867 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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() + "'";
}
}
}

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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);
}
}
}

View File

@ -0,0 +1,9 @@
package org.springframework.core.convert.support;
import org.springframework.core.convert.TypeDescriptor;
interface GenericConverter {
Object convert(Object source, TypeDescriptor type);
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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]);
}
}

View File

@ -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;
}

View File

@ -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>();
}

View File

@ -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>();
}

View File

@ -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));
}

View File

@ -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
}

View File

@ -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;
}
}