more converters; since 3.0
This commit is contained in:
parent
29139dfd1a
commit
1344a6d4d0
|
|
@ -750,6 +750,7 @@ public class GenericBinder implements Binder {
|
|||
if (cause instanceof SpelEvaluationException
|
||||
&& ((SpelEvaluationException) cause).getMessageCode() == SpelMessage.TYPE_CONVERSION_ERROR) {
|
||||
// TODO this could be a ConverterExecutorNotFoundException if no suitable converter was found
|
||||
cause.getCause().printStackTrace();
|
||||
ConversionFailedException failure = (ConversionFailedException) cause.getCause();
|
||||
MessageBuilder builder = new MessageBuilder(messageSource);
|
||||
builder.code("conversionFailed");
|
||||
|
|
|
|||
|
|
@ -280,6 +280,29 @@ public class GenericBinderTests {
|
|||
assertEquals("12345", bean.addresses.get(2).zip);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void bindToListSingleStringNoListFormatter() {
|
||||
binder.addBinding("addresses");
|
||||
//binder.registerFormatter(new GenericCollectionPropertyType(List.class, Address.class), new AddressListFormatter());
|
||||
Map<String, String> values = new LinkedHashMap<String, String>();
|
||||
values.put("addresses", "4655 Macy Lane:Melbourne:FL:35452,1234 Rostock Circle:Palm Bay:FL:32901,1977 Bel Aire Estates:Coker:AL:12345");
|
||||
BindingResults results = binder.bind(values);
|
||||
Assert.assertEquals(3, bean.addresses.size());
|
||||
assertEquals("4655 Macy Lane", bean.addresses.get(0).street);
|
||||
assertEquals("Melbourne", bean.addresses.get(0).city);
|
||||
assertEquals("FL", bean.addresses.get(0).state);
|
||||
assertEquals("35452", bean.addresses.get(0).zip);
|
||||
assertEquals("1234 Rostock Circle", bean.addresses.get(1).street);
|
||||
assertEquals("Palm Bay", bean.addresses.get(1).city);
|
||||
assertEquals("FL", bean.addresses.get(1).state);
|
||||
assertEquals("32901", bean.addresses.get(1).zip);
|
||||
assertEquals("1977 Bel Aire Estates", bean.addresses.get(2).street);
|
||||
assertEquals("Coker", bean.addresses.get(2).city);
|
||||
assertEquals("AL", bean.addresses.get(2).state);
|
||||
assertEquals("12345", bean.addresses.get(2).zip);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getListAsSingleString() {
|
||||
binder.addBinding("addresses");
|
||||
|
|
@ -348,7 +371,6 @@ public class GenericBinderTests {
|
|||
Map<String, String[]> values = new LinkedHashMap<String, String[]>();
|
||||
values.put("favoriteFoodsByGroup", new String[] { "DAIRY=Milk", "FRUIT=Peaches", "MEAT=Ham" });
|
||||
BindingResults results = binder.bind(values);
|
||||
System.out.println(results);
|
||||
Assert.assertEquals(3, bean.favoriteFoodsByGroup.size());
|
||||
assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY));
|
||||
assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT));
|
||||
|
|
@ -363,8 +385,6 @@ public class GenericBinderTests {
|
|||
values.put("favoriteFoodsByGroup['FRUIT']", "Peaches");
|
||||
values.put("favoriteFoodsByGroup['MEAT']", "Ham");
|
||||
BindingResults results = binder.bind(values);
|
||||
System.out.println(results);
|
||||
System.out.println(results);
|
||||
Assert.assertEquals(3, bean.favoriteFoodsByGroup.size());
|
||||
assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY));
|
||||
assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT));
|
||||
|
|
@ -377,7 +397,6 @@ public class GenericBinderTests {
|
|||
Map<String, String> values = new LinkedHashMap<String, String>();
|
||||
values.put("favoriteFoodsByGroup", "DAIRY=Milk FRUIT=Peaches MEAT=Ham");
|
||||
BindingResults results = binder.bind(values);
|
||||
System.out.println(results);
|
||||
Assert.assertEquals(3, bean.favoriteFoodsByGroup.size());
|
||||
assertEquals("Milk", bean.favoriteFoodsByGroup.get(FoodGroup.DAIRY));
|
||||
assertEquals("Peaches", bean.favoriteFoodsByGroup.get(FoodGroup.FRUIT));
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.springframework.core.style.StylerUtils;
|
|||
|
||||
/**
|
||||
* Thrown when an attempt to execute a type conversion fails.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConversionFailedException extends ConvertException {
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ package org.springframework.core.convert;
|
|||
|
||||
/**
|
||||
* Base class for exceptions thrown by the convert system.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class ConvertException extends RuntimeException {
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ package org.springframework.core.convert;
|
|||
|
||||
/**
|
||||
* Thrown when a suitable converter could not be found in a conversion service.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConverterNotFoundException extends ConvertException {
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ package org.springframework.core.convert;
|
|||
* <p>
|
||||
* Call {@link #convert(Object, Class)} to perform a thread-safe type conversion using this system.<br>
|
||||
* Call {@link #convert(Object, TypeDescriptor)} to perform a conversion with additional context about the targetType to convert to.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface TypeConverter {
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ import org.springframework.core.GenericCollectionTypeResolver;
|
|||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
// TODO doesn't support more than depth of one (eg. Map<String,List<Foo>> or List<String>[])
|
||||
/**
|
||||
* Context about a type to convert to.
|
||||
* @author Keith Donald
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class TypeDescriptor<T> {
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.springframework.core.convert.TypeConverter;
|
|||
* invoked behind a {@link TypeConverter}. They typically should not be called directly.
|
||||
* </p>
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface Converter<S, T> {
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.core.convert.converter;
|
|||
/**
|
||||
* A factory for "ranged" converters that can convert objects from S to subtypes of R.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @param <S> The source type converters created by this factory can convert from
|
||||
* @param <R> The target range (or base) type converters created by this factory can convert to;
|
||||
* for example {@link Number} for a set of number subtypes.
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@ import org.springframework.core.convert.TypeConverter;
|
|||
|
||||
/**
|
||||
* A meta interface a Converter may implement to describe what types he can convert between.
|
||||
* Implementing this interface is required for converters that do not declare their parameterized types S and T and expect to be registered with a {@link TypeConverter}.
|
||||
* Implementing this interface is required when registering converters that do not declare their parameterized types S and T with a {@link TypeConverter}.
|
||||
* Such Converters are often dynamically created by a {@link ConverterFactory}.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see Converter
|
||||
* @see SuperConverter
|
||||
* @see ConverterFactory
|
||||
*/
|
||||
public interface ConverterInfo {
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.springframework.core.convert.converter;
|
|||
/**
|
||||
* For registering converters with a type conversion system.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface ConverterRegistry {
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
abstract class AbstractCollectionConverter implements ConversionExecutor {
|
||||
|
||||
private GenericTypeConverter conversionService;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ 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 TypeConverter} implementations.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ArrayToArray extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetArrayType, GenericTypeConverter conversionService) {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ 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
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ArrayToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToCollection(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType,
|
||||
|
|
@ -35,9 +36,8 @@ class ArrayToCollection extends AbstractCollectionConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doExecute(Object sourceArray) throws Exception {
|
||||
Class implClass = CollectionConversionUtils.getImpl(getTargetCollectionType());
|
||||
Class implClass = ConversionUtils.getCollectionImpl((Class<? extends Collection>) getTargetCollectionType());
|
||||
Collection collection = (Collection) implClass.newInstance();
|
||||
int length = Array.getLength(sourceArray);
|
||||
ConversionExecutor elementConverter = getElementConverter();
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ import org.springframework.util.NumberUtils;
|
|||
|
||||
/**
|
||||
* Converts from a Character to any JDK-standard Number implementation.
|
||||
*
|
||||
* <p>
|
||||
* Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class
|
||||
* delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see java.lang.Byte
|
||||
* @see java.lang.Short
|
||||
* @see java.lang.Integer
|
||||
|
|
@ -33,9 +34,7 @@ import org.springframework.util.NumberUtils;
|
|||
* @see java.lang.Float
|
||||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see NumberUtils
|
||||
*/
|
||||
public class CharacterToNumberFactory implements ConverterFactory<Character, Number> {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,15 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||
|
||||
/**
|
||||
* Special converter that converts from target collection to a source array.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CollectionToArray extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType,
|
||||
public CollectionToArray(TypeDescriptor sourceCollectionType, TypeDescriptor targetArrayType,
|
||||
GenericTypeConverter conversionService) {
|
||||
super(sourceArrayType, targetCollectionType, conversionService);
|
||||
super(sourceCollectionType, targetArrayType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||
|
||||
/**
|
||||
* A converter that can convert from one collection type to another.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CollectionToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToCollection(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType,
|
||||
|
|
@ -33,10 +34,9 @@ class CollectionToCollection extends AbstractCollectionConverter {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doExecute(Object source) throws Exception {
|
||||
Collection sourceCollection = (Collection) source;
|
||||
Class implClass = CollectionConversionUtils.getImpl(getTargetCollectionType());
|
||||
Class implClass = ConversionUtils.getCollectionImpl((Class<? extends Collection>) getTargetCollectionType());
|
||||
Collection targetCollection = (Collection) implClass.newInstance();
|
||||
ConversionExecutor elementConverter = getElementConverter(sourceCollection);
|
||||
Iterator it = sourceCollection.iterator();
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ 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
|
||||
*/
|
||||
public interface ConversionExecutor {
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,11 @@
|
|||
*/
|
||||
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.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultTypeConverter extends GenericTypeConverter {
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeConverter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.converter.ConverterInfo;
|
||||
|
|
@ -36,9 +36,12 @@ import org.springframework.core.convert.converter.ConverterRegistry;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base implementation of a conversion service. Initially empty, e.g. no converters are registered by default.
|
||||
* TODO - object to collection/map converters
|
||||
* Base implementation of a conversion service.
|
||||
* Initially empty, e.g. no converters are registered by default.
|
||||
* @author Keith Donald
|
||||
* @see #add(Converter)
|
||||
* @see #add(ConverterFactory)
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
||||
|
|
@ -69,6 +72,9 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
|
||||
public void add(Converter converter) {
|
||||
List typeInfo = getRequiredTypeInfo(converter);
|
||||
if (typeInfo == null) {
|
||||
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> your Converter<S, T> converts between");
|
||||
}
|
||||
Class sourceType = (Class) typeInfo.get(0);
|
||||
Class targetType = (Class) typeInfo.get(1);
|
||||
Map sourceMap = getSourceMap(sourceType);
|
||||
|
|
@ -77,6 +83,9 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
|
||||
public void add(ConverterFactory<?, ?> converterFactory) {
|
||||
List 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");
|
||||
}
|
||||
Class sourceType = (Class) typeInfo.get(0);
|
||||
Class targetType = (Class) typeInfo.get(1);
|
||||
Map sourceMap = getSourceMap(sourceType);
|
||||
|
|
@ -145,9 +154,9 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
Assert.notNull(sourceClass, "The sourceType to convert from is required");
|
||||
Assert.notNull(targetType, "The targetType to convert to is required");
|
||||
if (targetType.getType() == null) {
|
||||
// TODO for Andy - is this correct way to handle the Null TypedValue?
|
||||
return NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
// TODO clean this if/else code up
|
||||
TypeDescriptor sourceType = TypeDescriptor.valueOf(sourceClass);
|
||||
if (sourceType.isArray()) {
|
||||
if (targetType.isArray()) {
|
||||
|
|
@ -161,14 +170,19 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
return new ArrayToCollection(sourceType, targetType, this);
|
||||
} else if (targetType.isMap()) {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
// string array to map; with string element values in format foo=bar
|
||||
return new StringArrayToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
// array to map
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// array to object
|
||||
return null;
|
||||
if (targetType.equals(String.class)) {
|
||||
// array to string;
|
||||
return null;
|
||||
} else {
|
||||
// array to object
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sourceType.isCollection()) {
|
||||
|
|
@ -178,14 +192,19 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
return new CollectionToArray(sourceType, targetType, this);
|
||||
} else if (targetType.isMap()) {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
// string collection to map; with string element values in format foo=bar
|
||||
return null;
|
||||
return new StringCollectionToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
// object collection to map
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// collection to object
|
||||
return null;
|
||||
if (targetType.equals(String.class)) {
|
||||
// collection to string;
|
||||
return null;
|
||||
} else {
|
||||
// collection to object
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sourceType.isMap()) {
|
||||
|
|
@ -193,16 +212,16 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
return new MapToMap(sourceType, targetType, this);
|
||||
} else if (targetType.isArray()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
// map to string array; with string element values in format foo=bar
|
||||
return null;
|
||||
return new MapToStringArray(sourceType, targetType, this);
|
||||
} else {
|
||||
// map to object array
|
||||
return null;
|
||||
}
|
||||
} else if (targetType.isCollection()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
// map to string collection; with string element values in format foo=bar
|
||||
return null;
|
||||
return new MapToStringCollection(sourceType, targetType, this);
|
||||
} else {
|
||||
// map to object collection
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -211,18 +230,24 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
}
|
||||
}
|
||||
if (targetType.isArray()) {
|
||||
// object to array
|
||||
return null;
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToArray(sourceType, targetType, this);
|
||||
} else {
|
||||
return new ObjectToArray(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isCollection()) {
|
||||
// object to collection
|
||||
return null;
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToCollection(sourceType, targetType, this);
|
||||
} else {
|
||||
return new ObjectToCollection(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isMap()) {
|
||||
// object to map
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
// object to map
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -246,43 +271,52 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
typeInfo.add(info.getSourceType());
|
||||
typeInfo.add(info.getTargetType());
|
||||
return typeInfo;
|
||||
} else {
|
||||
return getConverterTypeInfo(converter.getClass());
|
||||
}
|
||||
Class classToIntrospect = converter.getClass();
|
||||
}
|
||||
|
||||
private List getConverterTypeInfo(Class converterClass) {
|
||||
Class classToIntrospect = converterClass;
|
||||
while (classToIntrospect != null) {
|
||||
Type[] genericInterfaces = classToIntrospect.getGenericInterfaces();
|
||||
for (Type genericInterface : genericInterfaces) {
|
||||
if (genericInterface instanceof ParameterizedType) {
|
||||
ParameterizedType pInterface = (ParameterizedType) genericInterface;
|
||||
if (Converter.class.isAssignableFrom((Class) pInterface.getRawType())
|
||||
|| ConverterFactory.class.isAssignableFrom((Class) pInterface.getRawType())) {
|
||||
Class s = getParameterClass(pInterface.getActualTypeArguments()[0], converter.getClass());
|
||||
Class t = getParameterClass(pInterface.getActualTypeArguments()[1], converter.getClass());
|
||||
typeInfo.add(getParameterClass(s, converter.getClass()));
|
||||
typeInfo.add(getParameterClass(t, converter.getClass()));
|
||||
break;
|
||||
Type[] ifcs = classToIntrospect.getGenericInterfaces();
|
||||
for (Type ifc : ifcs) {
|
||||
if (ifc instanceof ParameterizedType) {
|
||||
ParameterizedType paramIfc = (ParameterizedType) ifc;
|
||||
Type rawType = paramIfc.getRawType();
|
||||
if (Converter.class.equals(rawType) || ConverterFactory.class.equals(rawType)) {
|
||||
List typeInfo = new ArrayList(2);
|
||||
Type arg1 = paramIfc.getActualTypeArguments()[0];
|
||||
if (arg1 instanceof TypeVariable) {
|
||||
arg1 = GenericTypeResolver.resolveTypeVariable((TypeVariable) arg1, converterClass);
|
||||
}
|
||||
if (arg1 instanceof Class) {
|
||||
typeInfo.add((Class) arg1);
|
||||
}
|
||||
Type arg2 = paramIfc.getActualTypeArguments()[1];
|
||||
if (arg2 instanceof TypeVariable) {
|
||||
arg2 = GenericTypeResolver.resolveTypeVariable((TypeVariable) arg2, converterClass);
|
||||
}
|
||||
if (arg2 instanceof Class) {
|
||||
typeInfo.add((Class) arg2);
|
||||
}
|
||||
if (typeInfo.size() == 2) {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
else if (Converter.class.isAssignableFrom((Class) rawType)) {
|
||||
return getConverterTypeInfo((Class) rawType);
|
||||
}
|
||||
}
|
||||
else if (Converter.class.isAssignableFrom((Class) ifc)) {
|
||||
return getConverterTypeInfo((Class) ifc);
|
||||
}
|
||||
}
|
||||
classToIntrospect = classToIntrospect.getSuperclass();
|
||||
}
|
||||
if (typeInfo.size() != 2) {
|
||||
throw new IllegalArgumentException("Unable to extract source and target class arguments from Converter ["
|
||||
+ converter.getClass().getName() + "]; does the Converter specify the <S, T> generic types?");
|
||||
}
|
||||
return typeInfo;
|
||||
return null;
|
||||
}
|
||||
|
||||
private Class getParameterClass(Type parameterType, Class converterClass) {
|
||||
if (parameterType instanceof TypeVariable) {
|
||||
parameterType = GenericTypeResolver.resolveTypeVariable((TypeVariable) parameterType, converterClass);
|
||||
}
|
||||
if (parameterType instanceof Class) {
|
||||
return (Class) parameterType;
|
||||
}
|
||||
throw new IllegalArgumentException("Unable to obtain the java.lang.Class for parameterType [" + parameterType
|
||||
+ "] on Converter [" + converterClass.getName() + "]");
|
||||
}
|
||||
|
||||
|
||||
private Map getSourceMap(Class sourceType) {
|
||||
Map sourceMap = (Map) sourceTypeConverters.get(sourceType);
|
||||
if (sourceMap == null) {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@
|
|||
*/
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
|
@ -27,6 +24,7 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class MapToMap implements ConversionExecutor {
|
||||
|
|
@ -37,7 +35,7 @@ class MapToMap implements ConversionExecutor {
|
|||
|
||||
private GenericTypeConverter conversionService;
|
||||
|
||||
private EntryConverter entryConverter;
|
||||
private MapEntryConverter entryConverter;
|
||||
|
||||
/**
|
||||
* Creates a new map-to-map converter
|
||||
|
|
@ -52,23 +50,23 @@ class MapToMap implements ConversionExecutor {
|
|||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
private EntryConverter createEntryConverter() {
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (sourceType.isMapEntryTypeKnown() && targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = conversionService.getConversionExecutor(sourceType.getMapKeyType(),
|
||||
TypeDescriptor.valueOf(targetType.getMapKeyType()));
|
||||
ConversionExecutor valueConverter = conversionService.getConversionExecutor(sourceType.getMapValueType(),
|
||||
TypeDescriptor.valueOf(targetType.getMapValueType()));
|
||||
return new EntryConverter(keyConverter, valueConverter);
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
} else {
|
||||
return EntryConverter.NO_OP_INSTANCE;
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
Map map = (Map) source;
|
||||
Map targetMap = (Map) getImpl(targetType.getType()).newInstance();
|
||||
EntryConverter converter = getEntryConverter(map);
|
||||
Map targetMap = (Map) ConversionUtils.getMapImpl(targetType.getType()).newInstance();
|
||||
MapEntryConverter converter = getEntryConverter(map);
|
||||
Iterator<Map.Entry<?, ?>> it = map.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry entry = it.next();
|
||||
|
|
@ -80,9 +78,9 @@ class MapToMap implements ConversionExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
private EntryConverter getEntryConverter(Map<?, ?> map) {
|
||||
EntryConverter entryConverter = this.entryConverter;
|
||||
if (entryConverter == EntryConverter.NO_OP_INSTANCE) {
|
||||
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) {
|
||||
|
|
@ -105,59 +103,10 @@ class MapToMap implements ConversionExecutor {
|
|||
break;
|
||||
}
|
||||
}
|
||||
entryConverter = new EntryConverter(keyConverter, valueConverter);
|
||||
entryConverter = new MapEntryConverter(keyConverter, valueConverter);
|
||||
}
|
||||
}
|
||||
return entryConverter;
|
||||
}
|
||||
|
||||
static Class<?> getImpl(Class<?> targetClass) {
|
||||
if (targetClass.isInterface()) {
|
||||
if (Map.class.equals(targetClass)) {
|
||||
return HashMap.class;
|
||||
} else if (SortedMap.class.equals(targetClass)) {
|
||||
return TreeMap.class;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported Map interface [" + targetClass.getName() + "]");
|
||||
}
|
||||
} else {
|
||||
return targetClass;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntryConverter {
|
||||
|
||||
public static final EntryConverter NO_OP_INSTANCE = new EntryConverter();
|
||||
|
||||
private ConversionExecutor keyConverter;
|
||||
|
||||
private ConversionExecutor valueConverter;
|
||||
|
||||
private EntryConverter() {
|
||||
|
||||
}
|
||||
|
||||
public EntryConverter(ConversionExecutor keyConverter, ConversionExecutor valueConverter) {
|
||||
this.keyConverter = keyConverter;
|
||||
this.valueConverter = valueConverter;
|
||||
}
|
||||
|
||||
public Object convertKey(Object key) {
|
||||
if (keyConverter != null) {
|
||||
return keyConverter.execute(key);
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertValue(Object value) {
|
||||
if (valueConverter != null) {
|
||||
return valueConverter.execute(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,18 +18,20 @@ package org.springframework.core.convert.support;
|
|||
import org.springframework.core.convert.ConversionFailedException;
|
||||
|
||||
/**
|
||||
* Conversion executor that does nothing. Access singleton at {@link #INSTANCE}.s
|
||||
* Conversion executor that does nothing.
|
||||
* Access singleton using {@link #INSTANCE}.
|
||||
* @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;
|
||||
}
|
||||
|
||||
private NoOpConversionExecutor() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import org.springframework.util.NumberUtils;
|
|||
|
||||
/**
|
||||
* Converts from any JDK-standard Number implementation to a Character.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see java.lang.Character
|
||||
* @see java.lang.Short
|
||||
* @see java.lang.Integer
|
||||
|
|
@ -30,8 +30,7 @@ import org.springframework.util.NumberUtils;
|
|||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class NumberToCharacter implements Converter<Number, Character> {
|
||||
public Character convert(Number source) {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ import org.springframework.util.NumberUtils;
|
|||
|
||||
/**
|
||||
* Converts from any JDK-standard Number implementation to any other JDK-standard Number implementation.
|
||||
*
|
||||
* <p>
|
||||
* Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class
|
||||
* delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see java.lang.Byte
|
||||
* @see java.lang.Short
|
||||
* @see java.lang.Integer
|
||||
|
|
@ -34,8 +34,7 @@ import org.springframework.util.NumberUtils;
|
|||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class NumberToNumberFactory implements ConverterFactory<Number, Number> {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2004-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.converter.Converter;
|
||||
|
|
@ -6,6 +21,7 @@ import org.springframework.core.convert.converter.Converter;
|
|||
* Simply calls {@link Object#toString()} to convert any object to a string.
|
||||
* Used by the {@link DefaultTypeConverter} as a fallback if there are no other explicit to string converters registered.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ObjectToString implements Converter<Object, String> {
|
||||
public String convert(Object source) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.springframework.core.style.ToStringCreator;
|
|||
/**
|
||||
* Default conversion executor implementation for converters.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StaticConversionExecutor implements ConversionExecutor {
|
||||
|
|
|
|||
|
|
@ -15,14 +15,18 @@
|
|||
*/
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StringArrayToMap implements ConversionExecutor {
|
||||
|
||||
|
|
@ -32,7 +36,7 @@ class StringArrayToMap implements ConversionExecutor {
|
|||
|
||||
private GenericTypeConverter conversionService;
|
||||
|
||||
private EntryConverter entryConverter;
|
||||
private MapEntryConverter entryConverter;
|
||||
|
||||
public StringArrayToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
|
|
@ -41,24 +45,25 @@ class StringArrayToMap implements ConversionExecutor {
|
|||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
private EntryConverter createEntryConverter() {
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = conversionService.getConversionExecutor(String.class,
|
||||
TypeDescriptor.valueOf(targetType.getMapKeyType()));
|
||||
ConversionExecutor valueConverter = conversionService.getConversionExecutor(String.class,
|
||||
TypeDescriptor.valueOf(targetType.getMapValueType()));
|
||||
return new EntryConverter(keyConverter, valueConverter);
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
} else {
|
||||
return EntryConverter.NO_OP_INSTANCE;
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
Map targetMap = (Map) getImpl(targetType.getType()).newInstance();
|
||||
String[] array = (String[]) source;
|
||||
for (String string : array) {
|
||||
String[] fields = string.split("=");
|
||||
Map targetMap = (Map) ConversionUtils.getMapImpl(targetType.getType()).newInstance();
|
||||
int length = Array.getLength(source);
|
||||
for (int i = 0; i < length; i++) {
|
||||
String property = (String) Array.get(source, i);
|
||||
String[] fields = property.split("=");
|
||||
String key = fields[0];
|
||||
String value = fields[1];
|
||||
targetMap.put(entryConverter.convertKey(key), entryConverter.convertValue(value));
|
||||
|
|
@ -69,53 +74,4 @@ class StringArrayToMap implements ConversionExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
static Class<?> getImpl(Class<?> targetClass) {
|
||||
if (targetClass.isInterface()) {
|
||||
if (Map.class.equals(targetClass)) {
|
||||
return HashMap.class;
|
||||
} else if (SortedMap.class.equals(targetClass)) {
|
||||
return TreeMap.class;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported Map interface [" + targetClass.getName() + "]");
|
||||
}
|
||||
} else {
|
||||
return targetClass;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EntryConverter {
|
||||
|
||||
public static final EntryConverter NO_OP_INSTANCE = new EntryConverter();
|
||||
|
||||
private ConversionExecutor keyConverter;
|
||||
|
||||
private ConversionExecutor valueConverter;
|
||||
|
||||
private EntryConverter() {
|
||||
|
||||
}
|
||||
|
||||
public EntryConverter(ConversionExecutor keyConverter, ConversionExecutor valueConverter) {
|
||||
this.keyConverter = keyConverter;
|
||||
this.valueConverter = valueConverter;
|
||||
}
|
||||
|
||||
public Object convertKey(Object key) {
|
||||
if (keyConverter != null) {
|
||||
return keyConverter.execute(key);
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertValue(Object value) {
|
||||
if (valueConverter != null) {
|
||||
return valueConverter.execute(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to a BigDecimal using {@link BigDecimal#BigDecimal(String).
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBigDecimal implements Converter<String, BigDecimal> {
|
||||
public BigDecimal convert(String source) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to a BigInteger using {@link BigInteger#BigInteger(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBigInteger implements Converter<String, BigInteger> {
|
||||
public BigInteger convert(String source) {
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts String to a Boolean. The trueString and falseStrings are configurable.
|
||||
*
|
||||
* @see #StringToBoolean(String, String)
|
||||
* @author Keith Donald
|
||||
* @see #StringToBoolean(String, String)
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBoolean implements Converter<String, Boolean> {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to a Byte and back.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToByte implements Converter<String, Byte> {
|
||||
public Byte convert(String source) {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to a Character and back.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToCharacter implements Converter<String, Character> {
|
||||
public Character convert(String source) {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to a Double using {@link Double#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToDouble implements Converter<String, Double> {
|
||||
public Double convert(String source) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,29 @@
|
|||
/*
|
||||
* Copyright 2004-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.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.converter.ConverterInfo;
|
||||
|
||||
/**
|
||||
* A factory for String to enum converters.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class StringToEnumFactory implements ConverterFactory<String, Enum> {
|
||||
|
||||
|
|
@ -10,14 +31,22 @@ public class StringToEnumFactory implements ConverterFactory<String, Enum> {
|
|||
return new StringToEnum(targetType);
|
||||
}
|
||||
|
||||
class StringToEnum<T extends Enum> implements Converter<String, T> {
|
||||
class StringToEnum<T extends Enum> implements Converter<String, T>, ConverterInfo {
|
||||
|
||||
private Class<T> enumType;
|
||||
|
||||
public StringToEnum(Class<T> enumType) {
|
||||
this.enumType = enumType;
|
||||
}
|
||||
|
||||
|
||||
public Class<String> getSourceType() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Class<T> getTargetType() {
|
||||
return enumType;
|
||||
}
|
||||
|
||||
public T convert(String source) throws Exception {
|
||||
return (T) Enum.valueOf(enumType, source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import org.springframework.core.convert.converter.Converter;
|
|||
|
||||
/**
|
||||
* Converts a String to Float using {@link Float#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToFloat implements Converter<String, Float> {
|
||||
public Float convert(String source) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.springframework.core.convert.converter.Converter;
|
|||
/**
|
||||
* Converts a String to an Integer using {@link Integer#valueOf(String)}.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToInteger implements Converter<String, Integer> {
|
||||
public Integer convert(String source) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.springframework.util.StringUtils;
|
|||
/**
|
||||
* Converts a String to a Locale using {@link StringUtils#parseLocaleString(String)}.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToLocale implements Converter<String, Locale> {
|
||||
public Locale convert(String source) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.springframework.core.convert.converter.Converter;
|
|||
/**
|
||||
* Converts a String to a Long using {@link Long#valueOf(String)}.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToLong implements Converter<String, Long> {
|
||||
public Long convert(String source) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,18 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StringToMap implements ConversionExecutor {
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.springframework.core.convert.converter.Converter;
|
|||
/**
|
||||
* Converts a String to a Short using {@link Short#valueOf(String)}.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToShort implements Converter<String, Short> {
|
||||
public Short convert(String source) {
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ public class GenericTypeConverterTests {
|
|||
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");
|
||||
|
|
@ -231,15 +230,15 @@ public class GenericTypeConverterTests {
|
|||
assertEquals(map.get(2), FooEnum.BAZ);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void convertObjectToArray() {
|
||||
String[] result = (String[]) converter.convert("1,2,3", String[].class);
|
||||
assertEquals(1, result.length);
|
||||
assertEquals("1,2,3", result[0]);
|
||||
assertEquals(3, result.length);
|
||||
assertEquals("1", result[0]);
|
||||
assertEquals("2", result[1]);
|
||||
assertEquals("3", result[2]);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void convertObjectToArrayWithElementConversion() {
|
||||
converter.add(new StringToInteger());
|
||||
|
|
|
|||
Loading…
Reference in New Issue