added convert(Object, TypeDescriptor) convenience method; collection and map tests
This commit is contained in:
@@ -34,20 +34,9 @@ public interface ConversionService {
|
||||
*/
|
||||
boolean canConvert(Class<?> sourceType, Class<?> targetType);
|
||||
|
||||
/**
|
||||
* Convert the source to targetType.
|
||||
* @param source the source object to convert (may be null)
|
||||
* @param targetType the target type to convert to (required)
|
||||
* @return the converted object, an instance of targetType
|
||||
* @throws ConversionException if an exception occurred
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
*/
|
||||
<T> T convert(Object source, Class<T> targetType);
|
||||
|
||||
/**
|
||||
* Returns true if objects of sourceType can be converted to the targetType.
|
||||
* The TypeDescriptors provide additional context about the field locations where conversion would occur, often object property locations.
|
||||
* This flavor of the canConvert operation exists mainly for use by a general purpose data mapping framework, and not for use by user code.
|
||||
* The TypeDescriptors provide additional context about the source and target locations where conversion would occur, often object property locations.
|
||||
* @param sourceType context about the source type to convert from (required)
|
||||
* @param targetType context about the target type to convert to (required)
|
||||
* @return true if a conversion can be performed between the source and target types, false if not
|
||||
@@ -58,13 +47,22 @@ public interface ConversionService {
|
||||
|
||||
/**
|
||||
* Convert the source to targetType.
|
||||
* The TypeDescriptors provide additional context about the field locations where conversion will occur, often object property locations.
|
||||
* This flavor of the convert operation exists mainly for use by a general purpose data mapping framework, and not for use by user code.
|
||||
* @param source the source object to convert (may be null)
|
||||
* @param targetType the target type to convert to (required)
|
||||
* @return the converted object, an instance of targetType
|
||||
* @throws ConversionException if a conversion exception occurred
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
*/
|
||||
<T> T convert(Object source, Class<T> targetType);
|
||||
|
||||
/**
|
||||
* Convert the source to targetType.
|
||||
* The TypeDescriptors provide additional context about the source and target locations where conversion will occur, often object property locations.
|
||||
* @param source the source object to convert (may be null)
|
||||
* @param sourceType context about the source type converting from (may be null if source is null)
|
||||
* @param targetType context about the target type to convert to (required)
|
||||
* @return the converted object, an instance of {@link TypeDescriptor#getObjectType() targetType}</code>
|
||||
* @throws ConversionException if an exception occurred
|
||||
* @throws ConversionException if a conversion exception occurred
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
* @throws IllegalArgumentException if sourceType is null but source is not null
|
||||
* @see TypeDescriptor#forObject(Object)
|
||||
|
||||
@@ -70,7 +70,7 @@ public class TypeDescriptor {
|
||||
|
||||
/**
|
||||
* Create a new type descriptor from a {@link MethodParameter}.
|
||||
* Use this constructor when a conversion point is a constructor parameter, method parameter, or method return value.
|
||||
* Use this constructor when a source or target conversion point is a constructor parameter, method parameter, or method return value.
|
||||
* @param methodParameter the method parameter
|
||||
*/
|
||||
public TypeDescriptor(MethodParameter methodParameter) {
|
||||
@@ -78,8 +78,8 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a field.
|
||||
* Use this constructor when a conversion point is a field.
|
||||
* Create a new type descriptor from a {@link Field}.
|
||||
* Use this constructor when source or target conversion point is a field.
|
||||
* @param field the field
|
||||
*/
|
||||
public TypeDescriptor(Field field) {
|
||||
@@ -87,8 +87,8 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a bean property.
|
||||
* Use this constructor when a target conversion point is a property on a Java class.
|
||||
* Create a new type descriptor from a {@link Property}.
|
||||
* Use this constructor when a source or target conversion point is a property on a Java class.
|
||||
* @param property the property
|
||||
*/
|
||||
public TypeDescriptor(Property property) {
|
||||
@@ -96,9 +96,9 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for the given class.
|
||||
* Use this to instruct the conversion system to convert to an object to a specific target type, when no type location such as a method parameter or field is available to provide additional conversion context.
|
||||
* Generally prefer use of {@link #forObject(Object)} for constructing source type descriptors for source objects.
|
||||
* Create a new type descriptor from the given type.
|
||||
* Use this to instruct the conversion system to convert an object to a specific target type, when no type location such as a method parameter or field is available to provide additional conversion context.
|
||||
* Generally prefer use of {@link #forObject(Object)} for constructing type descriptors from source objects, as it handles the null object case.
|
||||
* @param type the class
|
||||
* @return the type descriptor
|
||||
*/
|
||||
@@ -108,9 +108,10 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a java.util.Collection class.
|
||||
* Useful for supporting conversion of source Collection objects to other types.
|
||||
* Serves as an alternative to {@link #forObject(Object)} to be used when you cannot rely on Collection element introspection to resolve the element type.
|
||||
* Create a new type descriptor from a java.util.Collection type.
|
||||
* Useful for converting to typed Collections.
|
||||
* For example, a List<String> could be converted to a List<EmailAddress> by converting to a targetType built with this method.
|
||||
* The method call to construct such a TypeDescriptor would look something like: collection(List.class, TypeDescriptor.valueOf(EmailAddress.class));
|
||||
* @param collectionType the collection type, which must implement {@link Collection}.
|
||||
* @param elementType the collection's element type, used to convert collection elements
|
||||
* @return the collection type descriptor
|
||||
@@ -123,9 +124,10 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a java.util.Map class.
|
||||
* Useful for supporting the conversion of source Map objects to other types.
|
||||
* Serves as an alternative to {@link #forObject(Object)} to be used when you cannot rely on Map entry introspection to resolve the key and value type.
|
||||
* Create a new type descriptor from a java.util.Map type.
|
||||
* Useful for Converting to typed Maps.
|
||||
* For example, a Map<String, String> could be converted to a Map<Id, EmailAddress> by converting to a targetType built with this method:
|
||||
* The method call to construct such a TypeDescriptor would look something like: map(Map.class, TypeDescriptor.valueOf(Id.class), TypeDescriptor.valueOf(EmailAddress.class));
|
||||
* @param mapType the map type, which must implement {@link Map}.
|
||||
* @param keyType the map's key type, used to convert map keys
|
||||
* @param valueType the map's value type, used to convert map values
|
||||
@@ -201,16 +203,19 @@ public class TypeDescriptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the declared (non-generic) type of the wrapped parameter/field.
|
||||
* @return the declared type, or <code>null</code> if this is {@link TypeDescriptor#NULL}
|
||||
* The type of the backing class, method parameter, field, or property described by this TypeDescriptor.
|
||||
* Returns primitive types as-is.
|
||||
* See {@link #getObjectType()} for a variation of this operation that resolves primitive types to their corresponding Object types if necessary.
|
||||
* @return the type, or <code>null</code> if this is {@link TypeDescriptor#NULL}
|
||||
* @see #getObjectType()
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the declared type of the wrapped parameter/field.
|
||||
* Returns the Object wrapper type if the underlying type is a primitive.
|
||||
* Variation of {@link #getType()} that accounts for a primitive type by returning its object wrapper type.
|
||||
* This is useful for conversion service implementations that wish to normalize to object-based types and not work with primitive types directly.
|
||||
*/
|
||||
public Class<?> getObjectType() {
|
||||
return ClassUtils.resolvePrimitiveIfNecessary(getType());
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
@@ -139,14 +140,6 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
return canConvert(sourceType != null ? TypeDescriptor.valueOf(sourceType) : null, TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T convert(Object source, Class<T> targetType) {
|
||||
if (targetType == null) {
|
||||
throw new IllegalArgumentException("The targetType to convert to cannot be null");
|
||||
}
|
||||
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (targetType == null) {
|
||||
throw new IllegalArgumentException("The targetType to convert to cannot be null");
|
||||
@@ -168,6 +161,14 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T convert(Object source, Class<T> targetType) {
|
||||
if (targetType == null) {
|
||||
throw new IllegalArgumentException("The targetType to convert to cannot be null");
|
||||
}
|
||||
return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
if (targetType == null) {
|
||||
throw new IllegalArgumentException("The targetType to convert to cannot be null");
|
||||
@@ -190,6 +191,20 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience operation for converting a source object to the specified targetType, where the targetType is a descriptor that provides additional conversion context.
|
||||
* Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and encapsulates the construction of the sourceType descriptor using {@link TypeDescriptor#forObject(Object)}.
|
||||
* @param source the source object
|
||||
* @param targetType the target type
|
||||
* @return the converted value
|
||||
* @throws ConversionException if a conversion exception occurred
|
||||
* @throws IllegalArgumentException if targetType is null
|
||||
* @throws IllegalArgumentException if sourceType is null but source is not null
|
||||
*/
|
||||
public Object convert(Object source, TypeDescriptor targetType) {
|
||||
return convert(source, TypeDescriptor.forObject(source), targetType);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
List<String> converterStrings = new ArrayList<String>();
|
||||
for (Map<Class<?>, MatchableConverters> targetConverters : this.converters.values()) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.Map;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
|
||||
@@ -16,7 +16,13 @@
|
||||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import java.awt.*;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.AbstractList;
|
||||
@@ -34,12 +40,9 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
@@ -51,7 +54,7 @@ import org.springframework.core.convert.converter.ConverterRegistry;
|
||||
*/
|
||||
public class DefaultConversionTests {
|
||||
|
||||
private ConversionService conversionService = new DefaultConversionService();
|
||||
private DefaultConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
@Test
|
||||
public void testStringToCharacter() {
|
||||
@@ -574,6 +577,16 @@ public class DefaultConversionTests {
|
||||
assertEquals(new Integer(2), bar.get(1));
|
||||
assertEquals(new Integer(3), bar.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void collection() {
|
||||
List<String> strings = new ArrayList<String>();
|
||||
strings.add("3");
|
||||
strings.add("9");
|
||||
List<Integer> integers = (List<Integer>) conversionService.convert(strings, TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class)));
|
||||
assertEquals(new Integer(3), integers.get(0));
|
||||
assertEquals(new Integer(9), integers.get(1));
|
||||
}
|
||||
|
||||
public Map<Integer, FooEnum> genericMap = new HashMap<Integer, FooEnum>();
|
||||
|
||||
@@ -588,6 +601,16 @@ public class DefaultConversionTests {
|
||||
assertEquals(FooEnum.BAZ, map.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void map() {
|
||||
Map<String, String> strings = new HashMap<String, String>();
|
||||
strings.put("3", "9");
|
||||
strings.put("6", "31");
|
||||
Map<Integer, Integer> integers = (Map<Integer, Integer>) conversionService.convert(strings, TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(Integer.class)));
|
||||
assertEquals(new Integer(9), integers.get(3));
|
||||
assertEquals(new Integer(31), integers.get(6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertPropertiesToString() {
|
||||
Properties foo = new Properties();
|
||||
|
||||
Reference in New Issue
Block a user