revised core conversion package for BeanWrapper/BeanFactory integration
This commit is contained in:
parent
e9823b57b4
commit
45a0cadf8e
|
|
@ -21,6 +21,8 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
||||
/**
|
||||
* Abstract implementation of the {@link PropertyAccessor} interface.
|
||||
* Provides base implementations of all convenience methods, with the
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -145,7 +146,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
* Create new BeanWrapperImpl, wrapping a new instance of the specified class.
|
||||
* @param clazz class to instantiate and wrap
|
||||
*/
|
||||
public BeanWrapperImpl(Class clazz) {
|
||||
public BeanWrapperImpl(Class<?> clazz) {
|
||||
registerDefaultEditors();
|
||||
setWrappedInstance(BeanUtils.instantiateClass(clazz));
|
||||
}
|
||||
|
|
@ -365,8 +366,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
return false;
|
||||
}
|
||||
|
||||
public Object convertIfNecessary(
|
||||
Object value, Class requiredType, MethodParameter methodParam) throws TypeMismatchException {
|
||||
public <T> T convertIfNecessary(
|
||||
Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException {
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
|
||||
}
|
||||
|
|
@ -572,7 +573,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
}
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
Object value;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
|
|
@ -580,8 +581,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
public Object run() throws Exception {
|
||||
return readMethod.invoke(object, (Object[]) null);
|
||||
}
|
||||
},acc);
|
||||
} catch (PrivilegedActionException pae) {
|
||||
}, acc);
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
|
|
@ -625,7 +627,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
}
|
||||
else if (value instanceof Map) {
|
||||
Map map = (Map) value;
|
||||
Class mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
|
||||
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
|
||||
// IMPORTANT: Do not pass full property name in here - property editors
|
||||
// must not kick in for map keys but rather only for map values.
|
||||
Object convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
|
||||
|
|
@ -945,6 +947,11 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
|
||||
}
|
||||
}
|
||||
catch (ConversionException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.beans;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
||||
/**
|
||||
* Interface that encapsulates configuration methods for a PropertyAccessor.
|
||||
* Also extends the PropertyEditorRegistry interface, which defines methods
|
||||
|
|
@ -29,6 +31,17 @@ package org.springframework.beans;
|
|||
*/
|
||||
public interface ConfigurablePropertyAccessor extends PropertyAccessor, PropertyEditorRegistry, TypeConverter {
|
||||
|
||||
/**
|
||||
* Specify a Spring 3.0 ConversionService to use for converting
|
||||
* property values, as an alternative to JavaBeans PropertyEditors.
|
||||
*/
|
||||
void setConversionService(ConversionService conversionService);
|
||||
|
||||
/**
|
||||
* Return the associated ConversionService, if any.
|
||||
*/
|
||||
ConversionService getConversionService();
|
||||
|
||||
/**
|
||||
* Set whether to extract the old property value when applying a
|
||||
* property editor to a new value for a property.
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ import org.springframework.beans.propertyeditors.PropertiesEditor;
|
|||
import org.springframework.beans.propertyeditors.StringArrayPropertyEditor;
|
||||
import org.springframework.beans.propertyeditors.URIEditor;
|
||||
import org.springframework.beans.propertyeditors.URLEditor;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.ResourceArrayPropertyEditor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
|
@ -75,6 +76,8 @@ import org.springframework.util.ClassUtils;
|
|||
*/
|
||||
public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
private boolean defaultEditorsActive = false;
|
||||
|
||||
private boolean configValueEditorsActive = false;
|
||||
|
|
@ -90,6 +93,22 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
|
|||
private Map<Class, PropertyEditor> customEditorCache;
|
||||
|
||||
|
||||
/**
|
||||
* Specify a Spring 3.0 ConversionService to use for converting
|
||||
* property values, as an alternative to JavaBeans PropertyEditors.
|
||||
*/
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the associated ConversionService, if any.
|
||||
*/
|
||||
public ConversionService getConversionService() {
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Management of default editors
|
||||
//---------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import org.apache.commons.logging.LogFactory;
|
|||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
|
@ -160,6 +162,18 @@ class TypeConverterDelegate {
|
|||
// Custom editor for this type?
|
||||
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
|
||||
|
||||
// No custom editor but custom ConversionService specified?
|
||||
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
|
||||
if (editor == null && conversionService != null && convertedValue != null &&
|
||||
conversionService.canConvert(convertedValue.getClass(), requiredType)) {
|
||||
if (methodParam != null) {
|
||||
return (T) conversionService.convert(convertedValue, new TypeDescriptor(methodParam));
|
||||
}
|
||||
else {
|
||||
return conversionService.convert(convertedValue, requiredType);
|
||||
}
|
||||
}
|
||||
|
||||
// Value not of required type?
|
||||
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
|
||||
if (editor == null) {
|
||||
|
|
@ -265,7 +279,7 @@ class TypeConverterDelegate {
|
|||
* @return the new value, possibly the result of type conversion
|
||||
* @throws IllegalArgumentException if type conversion failed
|
||||
*/
|
||||
protected Object doConvertValue(Object oldValue, Object newValue, Class requiredType, PropertyEditor editor) {
|
||||
protected Object doConvertValue(Object oldValue, Object newValue, Class<?> requiredType, PropertyEditor editor) {
|
||||
Object convertedValue = newValue;
|
||||
boolean sharedEditor = false;
|
||||
|
||||
|
|
@ -307,6 +321,8 @@ class TypeConverterDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
Object returnValue = convertedValue;
|
||||
|
||||
if (requiredType != null && !requiredType.isArray() && convertedValue instanceof String[]) {
|
||||
// Convert String array to a comma-separated String.
|
||||
// Only applies if no PropertyEditor converted the String array before.
|
||||
|
|
@ -335,7 +351,7 @@ class TypeConverterDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
return convertedValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ public class TypeMismatchException extends PropertyAccessException {
|
|||
*/
|
||||
public TypeMismatchException(PropertyChangeEvent propertyChangeEvent, Class requiredType, Throwable cause) {
|
||||
super(propertyChangeEvent,
|
||||
"Failed to convert property value of type [" +
|
||||
ClassUtils.getDescriptiveType(propertyChangeEvent.getNewValue()) + "]" +
|
||||
"Failed to convert property value of type '" +
|
||||
ClassUtils.getDescriptiveType(propertyChangeEvent.getNewValue()) + "'" +
|
||||
(requiredType != null ?
|
||||
" to required type [" + ClassUtils.getQualifiedName(requiredType) + "]" : "") +
|
||||
" to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : "") +
|
||||
(propertyChangeEvent.getPropertyName() != null ?
|
||||
" for property '" + propertyChangeEvent.getPropertyName() + "'" : ""),
|
||||
cause);
|
||||
|
|
@ -83,8 +83,8 @@ public class TypeMismatchException extends PropertyAccessException {
|
|||
* @param cause the root cause (may be <code>null</code>)
|
||||
*/
|
||||
public TypeMismatchException(Object value, Class requiredType, Throwable cause) {
|
||||
super("Failed to convert value of type [" + ClassUtils.getDescriptiveType(value) + "]" +
|
||||
(requiredType != null ? " to required type [" + ClassUtils.getQualifiedName(requiredType) + "]" : ""),
|
||||
super("Failed to convert value of type '" + ClassUtils.getDescriptiveType(value) + "'" +
|
||||
(requiredType != null ? " to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : ""),
|
||||
cause);
|
||||
this.value = value;
|
||||
this.requiredType = requiredType;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
|
|||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.HierarchicalBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
|
|
@ -134,6 +135,17 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
|
|||
*/
|
||||
BeanExpressionResolver getBeanExpressionResolver();
|
||||
|
||||
/**
|
||||
* Specify a Spring 3.0 ConversionService to use for converting
|
||||
* property values, as an alternative to JavaBeans PropertyEditors.
|
||||
*/
|
||||
void setConversionService(ConversionService conversionService);
|
||||
|
||||
/**
|
||||
* Return the associated ConversionService, if any.
|
||||
*/
|
||||
ConversionService getConversionService();
|
||||
|
||||
/**
|
||||
* Add a PropertyEditorRegistrar to be applied to all bean creation processes.
|
||||
* <p>Such a registrar creates new PropertyEditor instances and registers them
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ import org.springframework.beans.factory.config.InstantiationAwareBeanPostProces
|
|||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.core.DecoratingClassLoader;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -120,6 +121,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
/** Resolution strategy for expressions in bean definition values */
|
||||
private BeanExpressionResolver beanExpressionResolver;
|
||||
|
||||
/** Spring 3.0 ConversionService to use instead of PropertyEditors */
|
||||
private ConversionService conversionService;
|
||||
|
||||
/** Custom PropertyEditorRegistrars to apply to the beans of this factory */
|
||||
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
|
||||
new LinkedHashSet<PropertyEditorRegistrar>(4);
|
||||
|
|
@ -620,6 +624,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return this.beanExpressionResolver;
|
||||
}
|
||||
|
||||
public void setConversionService(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public ConversionService getConversionService() {
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
|
||||
Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
|
||||
this.propertyEditorRegistrars.add(registrar);
|
||||
|
|
@ -669,6 +681,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
else {
|
||||
// Build default TypeConverter, registering custom editors.
|
||||
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
|
||||
typeConverter.setConversionService(getConversionService());
|
||||
registerCustomEditors(typeConverter);
|
||||
return typeConverter;
|
||||
}
|
||||
|
|
@ -937,6 +950,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @param bw the BeanWrapper to initialize
|
||||
*/
|
||||
protected void initBeanWrapper(BeanWrapper bw) {
|
||||
bw.setConversionService(getConversionService());
|
||||
registerCustomEditors(bw);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -37,13 +37,6 @@ import java.util.Properties;
|
|||
* @see java.util.Properties#load
|
||||
*/
|
||||
public class PropertiesEditor extends PropertyEditorSupport {
|
||||
|
||||
/**
|
||||
* Any of these characters, if they're first after whitespace or first
|
||||
* on a line, mean that the line is a comment and should be ignored.
|
||||
*/
|
||||
private final static String COMMENT_MARKERS = "#!";
|
||||
|
||||
|
||||
/**
|
||||
* Convert {@link String} into {@link Properties}, considering it as
|
||||
|
|
|
|||
|
|
@ -16,15 +16,6 @@
|
|||
|
||||
package org.springframework.beans.factory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessControlContext;
|
||||
|
|
@ -40,12 +31,19 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import test.beans.DerivedTestBean;
|
||||
import test.beans.DummyFactory;
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.LifecycleBean;
|
||||
import test.beans.NestedTestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.NotWritablePropertyException;
|
||||
|
|
@ -73,17 +71,12 @@ import org.springframework.beans.factory.xml.ConstructorDependenciesBean;
|
|||
import org.springframework.beans.factory.xml.DependenciesBean;
|
||||
import org.springframework.beans.propertyeditors.CustomNumberEditor;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import test.beans.DerivedTestBean;
|
||||
import test.beans.DummyFactory;
|
||||
import test.beans.ITestBean;
|
||||
import test.beans.LifecycleBean;
|
||||
import test.beans.NestedTestBean;
|
||||
import test.beans.TestBean;
|
||||
|
||||
/**
|
||||
* Tests properties population and autowire behavior.
|
||||
*
|
||||
|
|
@ -835,6 +828,24 @@ public final class DefaultListableBeanFactoryTests {
|
|||
assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomConverter() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
DefaultConversionService conversionService = new DefaultConversionService();
|
||||
conversionService.add(new Converter<String, Float>() {
|
||||
public Float convert(String source) throws Exception {
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.GERMAN);
|
||||
return nf.parse(source).floatValue();
|
||||
}
|
||||
});
|
||||
lbf.setConversionService(conversionService);
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.addPropertyValue("myFloat", "1,1");
|
||||
lbf.registerBeanDefinition("testBean", new RootBeanDefinition(TestBean.class, pvs));
|
||||
TestBean testBean = (TestBean) lbf.getBean("testBean");
|
||||
assertTrue(testBean.getMyFloat().floatValue() == 1.1f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomEditorWithBeanReference() {
|
||||
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ package org.springframework.context.expression;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.ast.CommonTypeDescriptors;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the keys
|
||||
|
|
@ -39,7 +39,7 @@ public class MapAccessor implements PropertyAccessor {
|
|||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((Map) target).get(name),CommonTypeDescriptors.OBJECT_TYPE_DESCRIPTOR);
|
||||
return new TypedValue(((Map) target).get(name), TypeDescriptor.valueOf(Object.class));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ public abstract class CollectionFactory {
|
|||
|
||||
private static final String NAVIGABLE_MAP_CLASS_NAME = "java.util.NavigableMap";
|
||||
|
||||
private static Class navigableSet = null;
|
||||
|
||||
private static Class navigableMap = null;
|
||||
|
||||
private static final Set<Class> approximableCollectionTypes = new HashSet<Class>(10);
|
||||
|
||||
private static final Set<Class> approximableMapTypes = new HashSet<Class>(6);
|
||||
|
|
@ -72,8 +76,10 @@ public abstract class CollectionFactory {
|
|||
|
||||
// New Java 6 collection interfaces
|
||||
try {
|
||||
approximableCollectionTypes.add(ClassUtils.forName(NAVIGABLE_SET_CLASS_NAME, CollectionFactory.class.getClassLoader()));
|
||||
approximableMapTypes.add(ClassUtils.forName(NAVIGABLE_MAP_CLASS_NAME, CollectionFactory.class.getClassLoader()));
|
||||
navigableSet = ClassUtils.forName(NAVIGABLE_SET_CLASS_NAME, CollectionFactory.class.getClassLoader());
|
||||
navigableMap = ClassUtils.forName(NAVIGABLE_MAP_CLASS_NAME, CollectionFactory.class.getClassLoader());
|
||||
approximableCollectionTypes.add(navigableSet);
|
||||
approximableMapTypes.add(navigableMap);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// not running on Java 6 or above...
|
||||
|
|
@ -187,7 +193,7 @@ public abstract class CollectionFactory {
|
|||
* @return <code>true</code> if the type is approximable,
|
||||
* <code>false</code> if it is not
|
||||
*/
|
||||
public static boolean isApproximableCollectionType(Class collectionType) {
|
||||
public static boolean isApproximableCollectionType(Class<?> collectionType) {
|
||||
return (collectionType != null && approximableCollectionTypes.contains(collectionType));
|
||||
}
|
||||
|
||||
|
|
@ -195,9 +201,9 @@ public abstract class CollectionFactory {
|
|||
* Create the most approximate collection for the given collection.
|
||||
* <p>Creates an ArrayList, TreeSet or linked Set for a List, SortedSet
|
||||
* or Set, respectively.
|
||||
* @param collection the original collection object
|
||||
* @param collection the original Collection object
|
||||
* @param initialCapacity the initial capacity
|
||||
* @return the new collection instance
|
||||
* @return the new Collection instance
|
||||
* @see java.util.ArrayList
|
||||
* @see java.util.TreeSet
|
||||
* @see java.util.LinkedHashSet
|
||||
|
|
@ -218,6 +224,45 @@ public abstract class CollectionFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the most appropriate collection for the given collection type.
|
||||
* <p>Creates an ArrayList, TreeSet or linked Set for a List, SortedSet
|
||||
* or Set, respectively.
|
||||
* @param collectionType the desired type of the target Collection
|
||||
* @param initialCapacity the initial capacity
|
||||
* @return the new Collection instance
|
||||
* @see java.util.ArrayList
|
||||
* @see java.util.TreeSet
|
||||
* @see java.util.LinkedHashSet
|
||||
*/
|
||||
public static Collection createCollection(Class<?> collectionType, int initialCapacity) {
|
||||
if (collectionType.isInterface()) {
|
||||
if (List.class.equals(collectionType)) {
|
||||
return new ArrayList(initialCapacity);
|
||||
}
|
||||
else if (SortedSet.class.equals(collectionType) || collectionType.equals(navigableSet)) {
|
||||
return new TreeSet();
|
||||
}
|
||||
else if (Set.class.equals(collectionType) || Collection.class.equals(collectionType)) {
|
||||
return new LinkedHashSet(initialCapacity);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unsupported Collection interface: " + collectionType.getName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!Collection.class.isAssignableFrom(collectionType)) {
|
||||
throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
|
||||
}
|
||||
try {
|
||||
return (Collection) collectionType.newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException("Could not instantiate Collection type: " + collectionType.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given map type is an approximable type,
|
||||
* i.e. a type that {@link #createApproximateMap} can approximate.
|
||||
|
|
@ -225,16 +270,16 @@ public abstract class CollectionFactory {
|
|||
* @return <code>true</code> if the type is approximable,
|
||||
* <code>false</code> if it is not
|
||||
*/
|
||||
public static boolean isApproximableMapType(Class mapType) {
|
||||
public static boolean isApproximableMapType(Class<?> mapType) {
|
||||
return (mapType != null && approximableMapTypes.contains(mapType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the most approximate map for the given map.
|
||||
* <p>Creates a TreeMap or linked Map for a SortedMap or Map, respectively.
|
||||
* @param map the original map object
|
||||
* @param map the original Map object
|
||||
* @param initialCapacity the initial capacity
|
||||
* @return the new collection instance
|
||||
* @return the new Map instance
|
||||
* @see java.util.TreeMap
|
||||
* @see java.util.LinkedHashMap
|
||||
*/
|
||||
|
|
@ -248,6 +293,40 @@ public abstract class CollectionFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the most approximate map for the given map.
|
||||
* <p>Creates a TreeMap or linked Map for a SortedMap or Map, respectively.
|
||||
* @param collectionType the desired type of the target Map
|
||||
* @param initialCapacity the initial capacity
|
||||
* @return the new Map instance
|
||||
* @see java.util.TreeMap
|
||||
* @see java.util.LinkedHashMap
|
||||
*/
|
||||
public static Map createMap(Class<?> mapType, int initialCapacity) {
|
||||
if (mapType.isInterface()) {
|
||||
if (Map.class.equals(mapType)) {
|
||||
return new LinkedHashMap(initialCapacity);
|
||||
}
|
||||
else if (SortedMap.class.equals(mapType) || mapType.equals(navigableMap)) {
|
||||
return new TreeMap();
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unsupported Map interface: " + mapType.getName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!Map.class.isAssignableFrom(mapType)) {
|
||||
throw new IllegalArgumentException("Unsupported Map type: " + mapType.getName());
|
||||
}
|
||||
try {
|
||||
return (Map) mapType.newInstance();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException("Could not instantiate Map type: " + mapType.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ConcurrentMap adapter for the JDK ConcurrentHashMap class.
|
||||
|
|
|
|||
|
|
@ -1,41 +1,46 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
/**
|
||||
* Base class for exceptions thrown by the convert system.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class ConvertException extends RuntimeException {
|
||||
public abstract class ConversionException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new conversion exception.
|
||||
* Construct a new conversion exception.
|
||||
* @param message the exception message
|
||||
* @param cause the cause
|
||||
*/
|
||||
public ConvertException(String message, Throwable cause) {
|
||||
public ConversionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new conversion exception.
|
||||
* Construct a new conversion exception.
|
||||
* @param message the exception message
|
||||
*/
|
||||
public ConvertException(String message) {
|
||||
public ConversionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,28 +1,31 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import org.springframework.core.style.StylerUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Thrown when an attempt to execute a type conversion fails.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConversionFailedException extends ConvertException {
|
||||
public class ConversionFailedException extends ConversionException {
|
||||
|
||||
private transient Object value;
|
||||
|
||||
|
|
@ -30,22 +33,23 @@ public class ConversionFailedException extends ConvertException {
|
|||
|
||||
private Class<?> targetType;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new conversion exception.
|
||||
* 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 cause the cause of the conversion failure
|
||||
*/
|
||||
public ConversionFailedException(Object value, Class<?> sourceType, Class<?> targetType, Throwable cause) {
|
||||
super(defaultMessage(value, sourceType, targetType, cause), cause);
|
||||
super(buildDefaultMessage(value, sourceType, targetType, cause), cause);
|
||||
this.value = value;
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new conversion exception.
|
||||
* 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
|
||||
|
|
@ -58,30 +62,33 @@ public class ConversionFailedException extends ConvertException {
|
|||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the actual value we tried to convert, an instance of {@link #getSourceType()}.
|
||||
* Return the actual value we tried to convert, an instance of {@link #getSourceType()}.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source type we tried to convert the value from.
|
||||
* Return the source type we tried to convert the value from.
|
||||
*/
|
||||
public Class<?> getSourceType() {
|
||||
return sourceType;
|
||||
return this.sourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target type we tried to convert the value to.
|
||||
*/
|
||||
public Class<?> getTargetType() {
|
||||
return targetType;
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
private static String defaultMessage(Object value, Class<?> sourceType, Class<?> targetType, Throwable cause) {
|
||||
return "Unable to convert value " + StylerUtils.style(value) + " from type [" + sourceType.getName()
|
||||
+ "] to type [" + targetType.getName() + "]; reason = '" + cause.getMessage() + "'";
|
||||
|
||||
private static String buildDefaultMessage(Object value, Class<?> sourceType, Class<?> targetType, Throwable cause) {
|
||||
return "Unable to convert value " + StylerUtils.style(value) + " from type '" +
|
||||
ClassUtils.getQualifiedName(sourceType) + "' to type '" +
|
||||
ClassUtils.getQualifiedName(targetType) + "'; reason = '" + cause.getMessage() + "'";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,32 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A service interface for type conversion. This is the entry point into the convert system.
|
||||
* <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.
|
||||
*
|
||||
* <p>Call {@link #convert(Object, Class)} to perform a thread-safe type conversion using this system.
|
||||
* 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 {
|
||||
public interface ConversionService {
|
||||
|
||||
/**
|
||||
* Returns true if objects of sourceType can be converted to targetType.
|
||||
|
|
@ -39,24 +42,24 @@ public interface TypeConverter {
|
|||
* @param targetType context about the target type to convert to
|
||||
* @return true if a conversion can be performed, false if not
|
||||
*/
|
||||
boolean canConvert(Class<?> sourceType, TypeDescriptor<?> targetType);
|
||||
boolean canConvert(Class<?> sourceType, TypeDescriptor targetType);
|
||||
|
||||
/**
|
||||
* Convert the source to targetType.
|
||||
* @param source the source to convert from (may be null)
|
||||
* @param targetType the target type to convert to
|
||||
* @return the converted object, an instance of targetType, or <code>null</code> if a null source was provided
|
||||
* @throws ConvertException if an exception occurred
|
||||
* @throws ConversionException if an exception occurred
|
||||
*/
|
||||
<S, T> T convert(S source, Class<T> targetType);
|
||||
<T> T convert(Object source, Class<T> targetType);
|
||||
|
||||
/**
|
||||
* Convert the source to type T needed by the conversion point.
|
||||
* @param source the source to convert from (may be null)
|
||||
* @param targetType context about the target type to convert to
|
||||
* @return the converted object, an instance of {@link TypeDescriptor#getType()}</code>, or <code>null</code> if a null source was provided
|
||||
* @throws ConvertException if an exception occurred
|
||||
* @throws ConversionException if an exception occurred
|
||||
*/
|
||||
<S, T> T convert(S source, TypeDescriptor<T> targetType);
|
||||
Object convert(Object source, TypeDescriptor targetType);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,33 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Thrown when a suitable converter could not be found in a conversion service.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConverterNotFoundException extends ConvertException {
|
||||
public class ConverterNotFoundException extends ConversionException {
|
||||
|
||||
private Class<?> sourceType;
|
||||
private final Class<?> sourceType;
|
||||
|
||||
private final Class<?> targetType;
|
||||
|
||||
private Class<?> targetType;
|
||||
|
||||
/**
|
||||
* Creates a new conversion executor not found exception.
|
||||
|
|
@ -38,17 +41,19 @@ public class ConverterNotFoundException extends ConvertException {
|
|||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the source type that was requested to convert from.
|
||||
*/
|
||||
public Class<?> getSourceType() {
|
||||
return sourceType;
|
||||
return this.sourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target type that was requested to convert to.
|
||||
*/
|
||||
public Class<?> getTargetType() {
|
||||
return targetType;
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
|
@ -24,19 +25,17 @@ import java.util.Map;
|
|||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Context about a type to convert to.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class TypeDescriptor<T> {
|
||||
public class TypeDescriptor {
|
||||
|
||||
/**
|
||||
* Constant value for the null object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final static TypeDescriptor NULL = new TypeDescriptor((Class<?>) null);
|
||||
|
||||
private MethodParameter methodParameter;
|
||||
|
|
@ -47,6 +46,7 @@ public class TypeDescriptor<T> {
|
|||
|
||||
private Class<?> type;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new descriptor for the given type.
|
||||
* Use this constructor when a conversion point comes from a source such as a Map or collection, where no additional context is available.
|
||||
|
|
@ -76,18 +76,40 @@ public class TypeDescriptor<T> {
|
|||
this.field = field;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the wrapped MethodParameter, if any.
|
||||
* <p>Note: Either MethodParameter or Field is available.
|
||||
* @return the MethodParameter, or <code>null</code> if none
|
||||
*/
|
||||
public MethodParameter getMethodParameter() {
|
||||
return this.methodParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wrapped Field, if any.
|
||||
* <p>Note: Either MethodParameter or Field is available.
|
||||
* @return the Field, or <code>null</code> if none
|
||||
*/
|
||||
public Field getField() {
|
||||
return this.field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the declared (non-generic) type of the wrapped parameter/field.
|
||||
* @return the declared type (never <code>null</code>)
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
if (type != null) {
|
||||
return wrapperType(type);
|
||||
} else if (field != null) {
|
||||
return wrapperType(field.getType());
|
||||
} else if (methodParameter != null) {
|
||||
return wrapperType(methodParameter.getParameterType());
|
||||
} else {
|
||||
if (this.type != null) {
|
||||
return wrapperType(this.type);
|
||||
}
|
||||
else if (this.field != null) {
|
||||
return wrapperType(this.field.getType());
|
||||
}
|
||||
else if (this.methodParameter != null) {
|
||||
return wrapperType(this.methodParameter.getParameterType());
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -99,7 +121,8 @@ public class TypeDescriptor<T> {
|
|||
Class<?> type = getType();
|
||||
if (type != null) {
|
||||
return getType().getName();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -109,11 +132,7 @@ public class TypeDescriptor<T> {
|
|||
*/
|
||||
public boolean isArray() {
|
||||
Class<?> type = getType();
|
||||
if (type != null) {
|
||||
return type.isArray();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (type != null && type.isArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,15 +143,17 @@ public class TypeDescriptor<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* If this type is an array type or {@link Collection} type, returns the underlying element type. Returns null if
|
||||
* the type is neither an array or collection.
|
||||
* If this type is an array type or {@link Collection} type, returns the underlying element type.
|
||||
* Returns null if the type is neither an array or collection.
|
||||
*/
|
||||
public Class<?> getElementType() {
|
||||
if (isArray()) {
|
||||
return getArrayComponentType();
|
||||
} else if (isCollection()) {
|
||||
}
|
||||
else if (isCollection()) {
|
||||
return getCollectionElementType();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +169,7 @@ public class TypeDescriptor<T> {
|
|||
* Is this descriptor for a map where the key type and value type are known?
|
||||
*/
|
||||
public boolean isMapEntryTypeKnown() {
|
||||
return isMap() && getMapKeyType() != null && getMapValueType() != null;
|
||||
return (isMap() && getMapKeyType() != null && getMapValueType() != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -156,11 +177,13 @@ public class TypeDescriptor<T> {
|
|||
* @return the generic type, or <code>null</code> if none
|
||||
*/
|
||||
public Class<?> getMapKeyType() {
|
||||
if (field != null) {
|
||||
if (this.field != null) {
|
||||
return GenericCollectionTypeResolver.getMapKeyFieldType(field);
|
||||
} else if (methodParameter != null) {
|
||||
return GenericCollectionTypeResolver.getMapKeyParameterType(methodParameter);
|
||||
} else {
|
||||
}
|
||||
else if (this.methodParameter != null) {
|
||||
return GenericCollectionTypeResolver.getMapKeyParameterType(this.methodParameter);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -170,11 +193,13 @@ public class TypeDescriptor<T> {
|
|||
* @return the generic type, or <code>null</code> if none
|
||||
*/
|
||||
public Class<?> getMapValueType() {
|
||||
if (field != null) {
|
||||
return GenericCollectionTypeResolver.getMapValueFieldType(field);
|
||||
} else if (methodParameter != null) {
|
||||
return GenericCollectionTypeResolver.getMapValueParameterType(methodParameter);
|
||||
} else {
|
||||
if (this.field != null) {
|
||||
return GenericCollectionTypeResolver.getMapValueFieldType(this.field);
|
||||
}
|
||||
else if (this.methodParameter != null) {
|
||||
return GenericCollectionTypeResolver.getMapValueParameterType(this.methodParameter);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -183,48 +208,26 @@ public class TypeDescriptor<T> {
|
|||
* Obtain the annotations associated with the wrapped parameter/field, if any.
|
||||
*/
|
||||
public Annotation[] getAnnotations() {
|
||||
if (field != null) {
|
||||
if (cachedFieldAnnotations == null) {
|
||||
cachedFieldAnnotations = field.getAnnotations();
|
||||
if (this.field != null) {
|
||||
if (this.cachedFieldAnnotations == null) {
|
||||
this.cachedFieldAnnotations = field.getAnnotations();
|
||||
}
|
||||
return cachedFieldAnnotations;
|
||||
} else if (methodParameter != null) {
|
||||
return methodParameter.getMethod().getAnnotations();
|
||||
} else {
|
||||
return this.cachedFieldAnnotations;
|
||||
}
|
||||
else if (this.methodParameter != null) {
|
||||
return this.methodParameter.getMethod().getAnnotations();
|
||||
}
|
||||
else {
|
||||
return new Annotation[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wrapped MethodParameter, if any.
|
||||
* <p>
|
||||
* Note: Either MethodParameter or Field is available.
|
||||
* @return the MethodParameter, or <code>null</code> if none
|
||||
*/
|
||||
public MethodParameter getMethodParameter() {
|
||||
return methodParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the wrapped Field, if any.
|
||||
* <p>
|
||||
* Note: Either MethodParameter or Field is available.
|
||||
* @return the Field, or <code>null</code> if none
|
||||
*/
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this type is an abstract class.
|
||||
*/
|
||||
public boolean isAbstractClass() {
|
||||
Class<?> type = getType();
|
||||
if (type != null) {
|
||||
return !getType().isInterface() && Modifier.isAbstract(getType().getModifiers());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (type != null && !getType().isInterface() && Modifier.isAbstract(getType().getModifiers()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -232,11 +235,7 @@ public class TypeDescriptor<T> {
|
|||
*/
|
||||
public boolean isInstance(Object obj) {
|
||||
Class<?> type = getType();
|
||||
if (type != null) {
|
||||
return getType().isInstance(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (type != null && getType().isInstance(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -244,33 +243,8 @@ public class TypeDescriptor<T> {
|
|||
* @param targetType the target type
|
||||
* @return true if this type is assignable to the target
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean isAssignableTo(TypeDescriptor targetType) {
|
||||
return targetType.getType().isAssignableFrom(getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new type descriptor for the given class.
|
||||
* @param type the class
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public static <T> TypeDescriptor<T> valueOf(Class<T> type) {
|
||||
// TODO needs a cache for common type descriptors
|
||||
return new TypeDescriptor<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new type descriptor for the class of the given object.
|
||||
* @param object the object
|
||||
* @return the type descriptor
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static TypeDescriptor forObject(Object object) {
|
||||
if (object == null) {
|
||||
return NULL;
|
||||
} else {
|
||||
return valueOf(object.getClass());
|
||||
}
|
||||
return ClassUtils.isAssignable(targetType.getType(), getType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -281,7 +255,8 @@ public class TypeDescriptor<T> {
|
|||
if (isArray()) {
|
||||
// TODO should properly handle multi dimensional arrays
|
||||
stringValue.append(getArrayComponentType().getName()).append("[]");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Class<?> clazz = getType();
|
||||
if (clazz==null) {
|
||||
return "null";
|
||||
|
|
@ -292,7 +267,8 @@ public class TypeDescriptor<T> {
|
|||
if (collectionType != null) {
|
||||
stringValue.append("<").append(collectionType.getName()).append(">");
|
||||
}
|
||||
} else if (isMap()) {
|
||||
}
|
||||
else if (isMap()) {
|
||||
Class<?> keyType = getMapKeyType();
|
||||
Class<?> valType = getMapValueType();
|
||||
if (keyType != null && valType != null) {
|
||||
|
|
@ -304,6 +280,7 @@ public class TypeDescriptor<T> {
|
|||
return stringValue.toString();
|
||||
}
|
||||
|
||||
|
||||
// internal helpers
|
||||
|
||||
private Class<?> wrapperType(Class<?> type) {
|
||||
|
|
@ -331,29 +308,49 @@ public class TypeDescriptor<T> {
|
|||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Class<?> getArrayComponentType() {
|
||||
return getType().getComponentType();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<?> getCollectionElementType() {
|
||||
if (type != null) {
|
||||
return GenericCollectionTypeResolver.getCollectionType((Class<? extends Collection>) type);
|
||||
} else if (field != null) {
|
||||
return GenericCollectionTypeResolver.getCollectionFieldType(field);
|
||||
} else {
|
||||
return GenericCollectionTypeResolver.getCollectionParameterType(methodParameter);
|
||||
if (this.type != null) {
|
||||
return GenericCollectionTypeResolver.getCollectionType((Class<? extends Collection>) this.type);
|
||||
}
|
||||
else if (this.field != null) {
|
||||
return GenericCollectionTypeResolver.getCollectionFieldType(this.field);
|
||||
}
|
||||
else {
|
||||
return GenericCollectionTypeResolver.getCollectionParameterType(this.methodParameter);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTypeAssignableTo(Class<?> clazz) {
|
||||
Class<?> type = getType();
|
||||
if (type != null) {
|
||||
return clazz.isAssignableFrom(type);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (type != null && ClassUtils.isAssignable(clazz, type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// static factory methods
|
||||
|
||||
/**
|
||||
* Creates a new type descriptor for the given class.
|
||||
* @param type the class
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public static TypeDescriptor valueOf(Class type) {
|
||||
// TODO needs a cache for common type descriptors
|
||||
return new TypeDescriptor(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new type descriptor for the class of the given object.
|
||||
* @param object the object
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public static TypeDescriptor forObject(Object object) {
|
||||
return (object == null ? NULL : valueOf(object.getClass()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter;
|
||||
|
||||
import org.springframework.core.convert.ConvertException;
|
||||
import org.springframework.core.convert.TypeConverter;
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
/**
|
||||
* A converter converts a source object of type S to a target of type T.
|
||||
* <p>
|
||||
* Implementations of this interface are thread-safe and can be shared. Converters are typically registered with and
|
||||
* invoked behind a {@link TypeConverter}. They typically should not be called directly.
|
||||
* </p>
|
||||
*
|
||||
* <p>Implementations of this interface are thread-safe and can be shared.
|
||||
* Converters are typically registered with and invoked behind a
|
||||
* {@link org.springframework.core.convert.ConversionService}.
|
||||
* They typically should not be called directly.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
|
|
@ -34,9 +34,9 @@ public interface Converter<S, T> {
|
|||
* @param source the source object to convert, which must be an instance of S
|
||||
* @return the converted object, which must be an instance of T
|
||||
* @throws Exception an exception occurred performing the conversion; may be any checked exception, the conversion
|
||||
* system will handle wrapping the failure in a {@link ConvertException} that provides a consistent type
|
||||
* system will handle wrapping the failure in a {@link org.springframework.core.convert.ConversionException} that provides a consistent type
|
||||
* conversion error context
|
||||
*/
|
||||
T convert(S source) throws Exception;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -17,6 +17,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
|
||||
|
|
@ -32,4 +33,5 @@ public interface ConverterFactory<S, R> {
|
|||
* @return A converter from S to T
|
||||
*/
|
||||
<T extends R> Converter<S, T> getConverter(Class<T> targetType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,28 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter;
|
||||
|
||||
import org.springframework.core.convert.TypeConverter;
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
/**
|
||||
* A meta interface a Converter may implement to describe what types he can convert between.
|
||||
* Implementing this interface is required when registering converters that do not declare their parameterized types S and T 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 org.springframework.core.convert.ConversionService}.
|
||||
* Such Converters are often dynamically created by a {@link ConverterFactory}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see Converter
|
||||
|
|
@ -31,11 +33,11 @@ public interface ConverterInfo {
|
|||
/**
|
||||
* The source type the converter converts from.
|
||||
*/
|
||||
public Class<?> getSourceType();
|
||||
Class<?> getSourceType();
|
||||
|
||||
/**
|
||||
* The target type the converter converts to.
|
||||
*/
|
||||
public Class<?> getTargetType();
|
||||
Class<?> getTargetType();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -17,6 +17,7 @@ package org.springframework.core.convert.converter;
|
|||
|
||||
/**
|
||||
* For registering converters with a type conversion system.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
|
|
@ -38,4 +39,5 @@ public interface ConverterRegistry {
|
|||
* @param targetType the target type
|
||||
*/
|
||||
void removeConverter(Class<?> sourceType, Class<?> targetType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,42 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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)
|
||||
* 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;
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private ConversionExecutor elementConverter;
|
||||
|
||||
private TypeDescriptor sourceCollectionType;
|
||||
|
||||
private TypeDescriptor targetCollectionType;
|
||||
|
||||
public AbstractCollectionConverter(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType, GenericTypeConverter 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;
|
||||
|
|
@ -43,15 +45,18 @@ abstract class AbstractCollectionConverter implements ConversionExecutor {
|
|||
if (sourceElementType != null && targetElementType != null) {
|
||||
ConversionExecutor executor = conversionService.getConversionExecutor(sourceElementType, TypeDescriptor.valueOf(targetElementType));
|
||||
if (executor != null) {
|
||||
elementConverter = executor;
|
||||
} else {
|
||||
elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
this.elementConverter = executor;
|
||||
}
|
||||
} else {
|
||||
elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The collection type to convert to.
|
||||
*/
|
||||
|
|
@ -63,11 +68,11 @@ abstract class AbstractCollectionConverter implements ConversionExecutor {
|
|||
* The type of elements in the target collection.
|
||||
*/
|
||||
protected Class<?> getTargetElementType() {
|
||||
return targetCollectionType.getElementType();
|
||||
return this.targetCollectionType.getElementType();
|
||||
}
|
||||
|
||||
protected GenericTypeConverter getConversionService() {
|
||||
return conversionService;
|
||||
protected GenericConversionService getConversionService() {
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,20 +80,23 @@ abstract class AbstractCollectionConverter implements ConversionExecutor {
|
|||
* Returns {@link NoOpConversionExecutor#INSTANCE} if no converter could be eagerly resolved from type descriptor metadata.
|
||||
*/
|
||||
protected ConversionExecutor getElementConverter() {
|
||||
return elementConverter;
|
||||
return this.elementConverter;
|
||||
}
|
||||
|
||||
|
||||
public Object execute(Object source) {
|
||||
try {
|
||||
return doExecute(source);
|
||||
} catch (Exception e) {
|
||||
throw new ConversionFailedException(source, sourceCollectionType.getType(), targetCollectionType.getType(), e);
|
||||
}
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -17,20 +17,19 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.core.convert.TypeConverter;
|
||||
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.
|
||||
* {@link org.springframework.core.convert.ConversionService} implementations.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ArrayToArray extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetArrayType, GenericTypeConverter conversionService) {
|
||||
public ArrayToArray(TypeDescriptor sourceArrayType, TypeDescriptor targetArrayType, GenericConversionService conversionService) {
|
||||
super(sourceArrayType, targetArrayType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,47 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ArrayToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public ArrayToCollection(TypeDescriptor sourceArrayType, TypeDescriptor targetCollectionType,
|
||||
GenericTypeConverter conversionService) {
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceArrayType, targetCollectionType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Object doExecute(Object sourceArray) throws Exception {
|
||||
Class implClass = ConversionUtils.getCollectionImpl((Class<? extends Collection>) getTargetCollectionType());
|
||||
Collection collection = (Collection) implClass.newInstance();
|
||||
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)));
|
||||
|
|
@ -47,4 +49,4 @@ class ArrayToCollection extends AbstractCollectionConverter {
|
|||
return collection;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
|
|
@ -21,9 +22,10 @@ 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
|
||||
*
|
||||
* <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
|
||||
|
|
@ -42,9 +44,10 @@ public class CharacterToNumberFactory implements ConverterFactory<Character, Num
|
|||
return new CharacterToNumber<T>(targetType);
|
||||
}
|
||||
|
||||
|
||||
private static class CharacterToNumber<T extends Number> implements Converter<Character, T> {
|
||||
|
||||
private Class<T> targetType;
|
||||
private final Class<T> targetType;
|
||||
|
||||
public CharacterToNumber(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
|
|
@ -53,6 +56,6 @@ public class CharacterToNumberFactory implements ConverterFactory<Character, Num
|
|||
public T convert(Character source) throws Exception {
|
||||
return NumberUtils.convertNumberToTargetClass((short) source.charValue(), targetType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -26,11 +27,10 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class CollectionToArray extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToArray(TypeDescriptor sourceCollectionType, TypeDescriptor targetArrayType,
|
||||
GenericTypeConverter conversionService) {
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceCollectionType, targetArrayType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.Iterator;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
|
|
@ -29,19 +30,17 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||
class CollectionToCollection extends AbstractCollectionConverter {
|
||||
|
||||
public CollectionToCollection(TypeDescriptor sourceCollectionType, TypeDescriptor targetCollectionType,
|
||||
GenericTypeConverter conversionService) {
|
||||
GenericConversionService conversionService) {
|
||||
super(sourceCollectionType, targetCollectionType, conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doExecute(Object source) throws Exception {
|
||||
Collection sourceCollection = (Collection) source;
|
||||
Class implClass = ConversionUtils.getCollectionImpl((Class<? extends Collection>) getTargetCollectionType());
|
||||
Collection targetCollection = (Collection) implClass.newInstance();
|
||||
Collection targetCollection = CollectionFactory.createCollection(getTargetCollectionType(), sourceCollection.size());
|
||||
ConversionExecutor elementConverter = getElementConverter(sourceCollection);
|
||||
Iterator it = sourceCollection.iterator();
|
||||
while (it.hasNext()) {
|
||||
targetCollection.add(elementConverter.execute(it.next()));
|
||||
for (Object aSourceCollection : sourceCollection) {
|
||||
targetCollection.add(elementConverter.execute(aSourceCollection));
|
||||
}
|
||||
return targetCollection;
|
||||
}
|
||||
|
|
@ -49,11 +48,10 @@ class CollectionToCollection extends AbstractCollectionConverter {
|
|||
private ConversionExecutor getElementConverter(Collection<?> source) {
|
||||
ConversionExecutor elementConverter = getElementConverter();
|
||||
if (elementConverter == NoOpConversionExecutor.INSTANCE && getTargetElementType() != null) {
|
||||
Iterator<?> it = source.iterator();
|
||||
while (it.hasNext()) {
|
||||
Object value = it.next();
|
||||
for (Object value : source) {
|
||||
if (value != null) {
|
||||
elementConverter = getConversionService().getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
|
||||
elementConverter = getConversionService().getConversionExecutor(
|
||||
value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -61,4 +59,4 @@ class CollectionToCollection extends AbstractCollectionConverter {
|
|||
return elementConverter;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,38 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
* 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 {
|
||||
interface ConversionExecutor {
|
||||
|
||||
/**
|
||||
* Convert the source.
|
||||
* @param source the source to convert
|
||||
* @throws ConversionFailedException if an exception occurs during type conversion
|
||||
*/
|
||||
public Object execute(Object source);
|
||||
Object execute(Object source);
|
||||
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Conversion utility code shared by internal conversion executors in this package.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConversionUtils {
|
||||
|
||||
/**
|
||||
* Get the java.util.Collection implementation class that should be used for the given target collection type.
|
||||
* @param targetCollectionType the target collection type, may be an interface
|
||||
* @return the collection impl to use
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Class<? extends Collection> getCollectionImpl(Class<? extends Collection> targetCollectionType) {
|
||||
if (targetCollectionType.isInterface()) {
|
||||
if (List.class.equals(targetCollectionType)) {
|
||||
return ArrayList.class;
|
||||
} else if (Set.class.equals(targetCollectionType)) {
|
||||
return LinkedHashSet.class;
|
||||
} else if (SortedSet.class.equals(targetCollectionType)) {
|
||||
return TreeSet.class;
|
||||
} else if (Collection.class.equals(targetCollectionType)) {
|
||||
return ArrayList.class;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported collection interface [" + targetCollectionType.getName() + "]");
|
||||
}
|
||||
} else {
|
||||
return targetCollectionType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the java.util.Map implementation class that should be used for the given target map type.
|
||||
* @param targetMapType the target map type, may be an interface
|
||||
* @return the map impl to use
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Class<? extends Map> getMapImpl(Class<? extends Map> targetMapType) {
|
||||
if (targetMapType.isInterface()) {
|
||||
if (Map.class.equals(targetMapType)) {
|
||||
return HashMap.class;
|
||||
} else if (SortedMap.class.equals(targetMapType)) {
|
||||
return TreeMap.class;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported Map interface [" + targetMapType.getName() + "]");
|
||||
}
|
||||
} else {
|
||||
return targetMapType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +1,34 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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 {
|
||||
public class DefaultConversionService extends GenericConversionService {
|
||||
|
||||
/**
|
||||
* Creates a new default conversion service, installing the default converters.
|
||||
* Create a new default conversion service, installing the default converters.
|
||||
*/
|
||||
public DefaultTypeConverter() {
|
||||
addDefaultConverters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all default converters to the conversion service.
|
||||
*/
|
||||
protected void addDefaultConverters() {
|
||||
public DefaultConversionService() {
|
||||
add(new StringToByte());
|
||||
add(new StringToBoolean());
|
||||
add(new StringToCharacter());
|
||||
|
|
@ -52,4 +47,4 @@ public class DefaultTypeConverter extends GenericTypeConverter {
|
|||
add(new CharacterToNumberFactory());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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.ParameterizedType;
|
||||
|
|
@ -26,8 +27,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
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;
|
||||
|
|
@ -38,58 +39,59 @@ import org.springframework.util.Assert;
|
|||
/**
|
||||
* Base implementation of a conversion service.
|
||||
* Initially empty, e.g. no converters are registered by default.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see #add(Converter)
|
||||
* @see #add(ConverterFactory)
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
||||
public class GenericConversionService implements ConversionService, ConverterRegistry {
|
||||
|
||||
private ConversionService parent;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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 sourceTypeConverters = new HashMap();
|
||||
private final Map<Class, Map<Class, Object>> sourceTypeConverters = new HashMap<Class, Map<Class, Object>>();
|
||||
|
||||
private TypeConverter parent;
|
||||
|
||||
/**
|
||||
* Returns the parent of this conversion service. Could be null.
|
||||
*/
|
||||
public TypeConverter getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parent of this conversion service. This is optional.
|
||||
*/
|
||||
public void setParent(TypeConverter parent) {
|
||||
public void setParent(ConversionService parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent of this conversion service. Could be null.
|
||||
*/
|
||||
public ConversionService getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
|
||||
// implementing ConverterRegistry
|
||||
|
||||
public void add(Converter converter) {
|
||||
List typeInfo = getRequiredTypeInfo(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");
|
||||
}
|
||||
Class sourceType = (Class) typeInfo.get(0);
|
||||
Class targetType = (Class) typeInfo.get(1);
|
||||
Map sourceMap = getSourceMap(sourceType);
|
||||
sourceMap.put(targetType, converter);
|
||||
Class sourceType = typeInfo.get(0);
|
||||
Class targetType = typeInfo.get(1);
|
||||
getSourceMap(sourceType).put(targetType, converter);
|
||||
}
|
||||
|
||||
public void add(ConverterFactory<?, ?> converterFactory) {
|
||||
List typeInfo = getRequiredTypeInfo(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");
|
||||
}
|
||||
Class sourceType = (Class) typeInfo.get(0);
|
||||
Class targetType = (Class) typeInfo.get(1);
|
||||
Map sourceMap = getSourceMap(sourceType);
|
||||
sourceMap.put(targetType, converterFactory);
|
||||
Class sourceType = typeInfo.get(0);
|
||||
Class targetType = typeInfo.get(1);
|
||||
getSourceMap(sourceType).put(targetType, converterFactory);
|
||||
}
|
||||
|
||||
public void removeConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
|
|
@ -108,40 +110,45 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
// implementing TypeConverter
|
||||
// implementing ConversionService
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
|
||||
return canConvert(sourceType, TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public boolean canConvert(Class<?> sourceType, TypeDescriptor<?> targetType) {
|
||||
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) {
|
||||
ConversionExecutor executor = getConversionExecutor(sourceType, targetType);
|
||||
if (executor != null) {
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (parent != null) {
|
||||
return parent.canConvert(sourceType, targetType);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <S, T> T convert(S source, Class<T> targetType) {
|
||||
return convert(source, TypeDescriptor.valueOf(targetType));
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T convert(Object source, Class<T> targetType) {
|
||||
return (T) convert(source, TypeDescriptor.valueOf(targetType));
|
||||
}
|
||||
|
||||
public <S, T> T convert(S source, TypeDescriptor<T> targetType) {
|
||||
public Object convert(Object source, TypeDescriptor targetType) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
ConversionExecutor executor = getConversionExecutor(source.getClass(), targetType);
|
||||
if (executor != null) {
|
||||
return (T) executor.execute(source);
|
||||
} else {
|
||||
if (parent != null) {
|
||||
return parent.convert(source, targetType);
|
||||
} else {
|
||||
return executor.execute(source);
|
||||
}
|
||||
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 sourceType [" + source.getClass().getName()
|
||||
+ "] to targetType [" + targetType.getName() + "]");
|
||||
|
|
@ -149,8 +156,9 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
ConversionExecutor getConversionExecutor(Class sourceClass, TypeDescriptor targetType)
|
||||
ConversionExecutor getConversionExecutor(Class<?> sourceClass, TypeDescriptor targetType)
|
||||
throws ConverterNotFoundException {
|
||||
|
||||
Assert.notNull(sourceClass, "The sourceType to convert from is required");
|
||||
Assert.notNull(targetType, "The targetType to convert to is required");
|
||||
if (targetType.getType() == null) {
|
||||
|
|
@ -161,25 +169,30 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
if (sourceType.isArray()) {
|
||||
if (targetType.isArray()) {
|
||||
return new ArrayToArray(sourceType, targetType, this);
|
||||
} else if (targetType.isCollection()) {
|
||||
}
|
||||
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 concrete implementation instead");
|
||||
}
|
||||
return new ArrayToCollection(sourceType, targetType, this);
|
||||
} else if (targetType.isMap()) {
|
||||
}
|
||||
else if (targetType.isMap()) {
|
||||
if (sourceType.getElementType().equals(String.class)) {
|
||||
return new StringArrayToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// array to map
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (targetType.equals(String.class)) {
|
||||
// array to string;
|
||||
}
|
||||
else {
|
||||
if (targetType.getType().equals(String.class)) {
|
||||
// array to string
|
||||
return null;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// array to object
|
||||
return null;
|
||||
}
|
||||
|
|
@ -188,20 +201,24 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
if (sourceType.isCollection()) {
|
||||
if (targetType.isCollection()) {
|
||||
return new CollectionToCollection(sourceType, targetType, this);
|
||||
} else if (targetType.isArray()) {
|
||||
}
|
||||
else if (targetType.isArray()) {
|
||||
return new CollectionToArray(sourceType, targetType, this);
|
||||
} else if (targetType.isMap()) {
|
||||
}
|
||||
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.equals(String.class)) {
|
||||
}
|
||||
else {
|
||||
if (targetType.getType().equals(String.class)) {
|
||||
// collection to string;
|
||||
return null;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// collection to object
|
||||
return null;
|
||||
}
|
||||
|
|
@ -210,21 +227,26 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
if (sourceType.isMap()) {
|
||||
if (targetType.isMap()) {
|
||||
return new MapToMap(sourceType, targetType, this);
|
||||
} else if (targetType.isArray()) {
|
||||
}
|
||||
else if (targetType.isArray()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
return new MapToStringArray(sourceType, targetType, this);
|
||||
} else {
|
||||
return new MapToStringArray(targetType, this);
|
||||
}
|
||||
else {
|
||||
// map to object array
|
||||
return null;
|
||||
}
|
||||
} else if (targetType.isCollection()) {
|
||||
}
|
||||
else if (targetType.isCollection()) {
|
||||
if (targetType.getElementType().equals(String.class)) {
|
||||
return new MapToStringCollection(sourceType, targetType, this);
|
||||
} else {
|
||||
return new MapToStringCollection(targetType, this);
|
||||
}
|
||||
else {
|
||||
// map to object collection
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// map to object
|
||||
return null;
|
||||
}
|
||||
|
|
@ -232,21 +254,24 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
if (targetType.isArray()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToArray(sourceType, targetType, this);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return new ObjectToArray(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isCollection()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToCollection(sourceType, targetType, this);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return new ObjectToCollection(sourceType, targetType, this);
|
||||
}
|
||||
}
|
||||
if (targetType.isMap()) {
|
||||
if (sourceType.getType().equals(String.class)) {
|
||||
return new StringToMap(sourceType, targetType, this);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// object to map
|
||||
return null;
|
||||
}
|
||||
|
|
@ -257,26 +282,29 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
Converter converter = findRegisteredConverter(sourceType.getType(), targetType.getType());
|
||||
if (converter != null) {
|
||||
return new StaticConversionExecutor(sourceType, targetType, converter);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// internal helpers
|
||||
|
||||
private List getRequiredTypeInfo(Object converter) {
|
||||
List typeInfo = new ArrayList(2);
|
||||
private List<Class> getRequiredTypeInfo(Object converter) {
|
||||
List<Class> typeInfo = new ArrayList<Class>(2);
|
||||
if (converter instanceof ConverterInfo) {
|
||||
ConverterInfo info = (ConverterInfo) converter;
|
||||
typeInfo.add(info.getSourceType());
|
||||
typeInfo.add(info.getTargetType());
|
||||
return typeInfo;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return getConverterTypeInfo(converter.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private List getConverterTypeInfo(Class converterClass) {
|
||||
private List<Class> getConverterTypeInfo(Class converterClass) {
|
||||
Class classToIntrospect = converterClass;
|
||||
while (classToIntrospect != null) {
|
||||
Type[] ifcs = classToIntrospect.getGenericInterfaces();
|
||||
|
|
@ -285,7 +313,7 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
ParameterizedType paramIfc = (ParameterizedType) ifc;
|
||||
Type rawType = paramIfc.getRawType();
|
||||
if (Converter.class.equals(rawType) || ConverterFactory.class.equals(rawType)) {
|
||||
List typeInfo = new ArrayList(2);
|
||||
List<Class> typeInfo = new ArrayList<Class>(2);
|
||||
Type arg1 = paramIfc.getActualTypeArguments()[0];
|
||||
if (arg1 instanceof TypeVariable) {
|
||||
arg1 = GenericTypeResolver.resolveTypeVariable((TypeVariable) arg1, converterClass);
|
||||
|
|
@ -317,10 +345,10 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Map getSourceMap(Class sourceType) {
|
||||
Map sourceMap = (Map) sourceTypeConverters.get(sourceType);
|
||||
private Map<Class, Object> getSourceMap(Class sourceType) {
|
||||
Map<Class, Object> sourceMap = sourceTypeConverters.get(sourceType);
|
||||
if (sourceMap == null) {
|
||||
sourceMap = new HashMap();
|
||||
sourceMap = new HashMap<Class, Object>();
|
||||
sourceTypeConverters.put(sourceType, sourceMap);
|
||||
}
|
||||
return sourceMap;
|
||||
|
|
@ -328,29 +356,30 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
|
||||
private Converter findRegisteredConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
if (sourceType.isInterface()) {
|
||||
LinkedList classQueue = new LinkedList();
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = (Class) classQueue.removeLast();
|
||||
Map converters = getConvertersForSource(currentClass);
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, Object> converters = getConvertersForSource(currentClass);
|
||||
System.out.println("Source:" + currentClass);
|
||||
Converter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
classQueue.addFirst(interfaces[i]);
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
Map objectConverters = getConvertersForSource(Object.class);
|
||||
Map<Class, Object> objectConverters = getConvertersForSource(Object.class);
|
||||
return getConverter(objectConverters, targetType);
|
||||
} else {
|
||||
LinkedList classQueue = new LinkedList();
|
||||
}
|
||||
else {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(sourceType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = (Class) classQueue.removeLast();
|
||||
Map converters = getConvertersForSource(currentClass);
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Map<Class, Object> converters = getConvertersForSource(currentClass);
|
||||
Converter converter = getConverter(converters, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
|
|
@ -359,41 +388,45 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
classQueue.addFirst(currentClass.getSuperclass());
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
classQueue.addFirst(interfaces[i]);
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Map getConvertersForSource(Class sourceType) {
|
||||
Map converters = (Map) sourceTypeConverters.get(sourceType);
|
||||
return converters != null ? converters : Collections.emptyMap();
|
||||
private Map<Class, Object> getConvertersForSource(Class<?> sourceType) {
|
||||
Map<Class, Object> converters = this.sourceTypeConverters.get(sourceType);
|
||||
if (converters == null) {
|
||||
converters = Collections.emptyMap();
|
||||
}
|
||||
return converters;
|
||||
}
|
||||
|
||||
private Converter getConverter(Map converters, Class targetType) {
|
||||
private Converter getConverter(Map<Class, Object> converters, Class<?> targetType) {
|
||||
if (targetType.isInterface()) {
|
||||
LinkedList classQueue = new LinkedList();
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(targetType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = (Class) classQueue.removeLast();
|
||||
Converter converter = getConverterImpl(converters, currentClass, targetType);
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Converter converter = getConverter(converters, currentClass, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
classQueue.addFirst(interfaces[i]);
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
return getConverterImpl(converters, Object.class, targetType);
|
||||
} else {
|
||||
LinkedList classQueue = new LinkedList();
|
||||
return getConverter(converters, Object.class, targetType);
|
||||
}
|
||||
else {
|
||||
LinkedList<Class> classQueue = new LinkedList<Class>();
|
||||
classQueue.addFirst(targetType);
|
||||
while (!classQueue.isEmpty()) {
|
||||
Class currentClass = (Class) classQueue.removeLast();
|
||||
Converter converter = getConverterImpl(converters, currentClass, targetType);
|
||||
Class currentClass = classQueue.removeLast();
|
||||
Converter converter = getConverter(converters, currentClass, targetType);
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
|
|
@ -401,22 +434,24 @@ public class GenericTypeConverter implements TypeConverter, ConverterRegistry {
|
|||
classQueue.addFirst(currentClass.getSuperclass());
|
||||
}
|
||||
Class[] interfaces = currentClass.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
classQueue.addFirst(interfaces[i]);
|
||||
for (Class ifc : interfaces) {
|
||||
classQueue.addFirst(ifc);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Converter getConverterImpl(Map converters, Class currentClass, Class targetType) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Converter getConverter(Map<Class, Object> converters, Class<?> currentClass, Class<?> targetType) {
|
||||
Object converter = converters.get(currentClass);
|
||||
if (converter == null) {
|
||||
return null;
|
||||
}
|
||||
if (converter instanceof Converter) {
|
||||
return (Converter) converter;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return ((ConverterFactory) converter).getConverter(targetType);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +1,59 @@
|
|||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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();
|
||||
public static final MapEntryConverter NO_OP_INSTANCE = new MapEntryConverter(null, null);
|
||||
|
||||
private ConversionExecutor keyConverter;
|
||||
|
||||
private ConversionExecutor valueConverter;
|
||||
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 (keyConverter != null) {
|
||||
return keyConverter.execute(key);
|
||||
} else {
|
||||
if (this.keyConverter != null) {
|
||||
return this.keyConverter.execute(key);
|
||||
}
|
||||
else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertValue(Object value) {
|
||||
if (valueConverter != null) {
|
||||
return valueConverter.execute(value);
|
||||
} else {
|
||||
if (this.valueConverter != null) {
|
||||
return this.valueConverter.execute(value);
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// internal
|
||||
|
||||
private MapEntryConverter() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +1,44 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.Iterator;
|
||||
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.
|
||||
* 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 {
|
||||
|
||||
private TypeDescriptor sourceType;
|
||||
private final TypeDescriptor sourceType;
|
||||
|
||||
private TypeDescriptor targetType;
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private GenericTypeConverter conversionService;
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
private MapEntryConverter entryConverter;
|
||||
|
||||
/**
|
||||
* Creates a new map-to-map converter
|
||||
|
|
@ -43,38 +46,40 @@ class MapToMap implements ConversionExecutor {
|
|||
* @param targetType the target map type
|
||||
* @param conversionService the conversion service
|
||||
*/
|
||||
public MapToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
public MapToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.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()));
|
||||
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 {
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
Map map = (Map) source;
|
||||
Map targetMap = (Map) ConversionUtils.getMapImpl(targetType.getType()).newInstance();
|
||||
Map<?, ?> map = (Map<?, ?>) source;
|
||||
Map targetMap = CollectionFactory.createMap(this.targetType.getType(), map.size());
|
||||
MapEntryConverter converter = getEntryConverter(map);
|
||||
Iterator<Map.Entry<?, ?>> it = map.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry entry = it.next();
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
targetMap.put(converter.convertKey(entry.getKey()), converter.convertValue(entry.getValue()));
|
||||
}
|
||||
return targetMap;
|
||||
} catch (Exception e) {
|
||||
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,18 +91,16 @@ class MapToMap implements ConversionExecutor {
|
|||
if (targetKeyType != null && targetValueType != null) {
|
||||
ConversionExecutor keyConverter = null;
|
||||
ConversionExecutor valueConverter = null;
|
||||
Iterator<?> it = map.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) it.next();
|
||||
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));
|
||||
keyConverter = conversionService
|
||||
.getConversionExecutor(key.getClass(), TypeDescriptor.valueOf(targetKeyType));
|
||||
}
|
||||
if (valueConverter == null && value != null) {
|
||||
valueConverter = conversionService.getConversionExecutor(value.getClass(), TypeDescriptor
|
||||
.valueOf(targetValueType));
|
||||
valueConverter = conversionService
|
||||
.getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(targetValueType));
|
||||
}
|
||||
if (keyConverter != null && valueConverter != null) {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -24,45 +25,48 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class MapToStringArray implements ConversionExecutor {
|
||||
|
||||
private TypeDescriptor targetType;
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private GenericTypeConverter conversionService;
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private MapEntryConverter entryConverter;
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
public MapToStringArray(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
|
||||
public MapToStringArray(TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.entryConverter = createEntryConverter();
|
||||
}
|
||||
|
||||
|
||||
private MapEntryConverter createEntryConverter() {
|
||||
if (targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = conversionService.getConversionExecutor(targetType.getMapKeyType(),
|
||||
if (this.targetType.isMapEntryTypeKnown()) {
|
||||
ConversionExecutor keyConverter = this.conversionService.getConversionExecutor(this.targetType.getMapKeyType(),
|
||||
TypeDescriptor.valueOf(String.class));
|
||||
ConversionExecutor valueConverter = conversionService.getConversionExecutor(targetType.getMapValueType(),
|
||||
ConversionExecutor valueConverter = this.conversionService.getConversionExecutor(this.targetType.getMapValueType(),
|
||||
TypeDescriptor.valueOf(String.class));
|
||||
return new MapEntryConverter(keyConverter, valueConverter);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Map sourceMap = (Map) source;
|
||||
Object array = Array.newInstance(targetType.getElementType(), sourceMap.size());
|
||||
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 = entryConverter.convertKey(key) + "=" + entryConverter.convertValue(value);
|
||||
String property = this.entryConverter.convertKey(key) + "=" + this.entryConverter.convertValue(value);
|
||||
Array.set(array, i, property);
|
||||
i++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -23,25 +24,27 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class MapToStringCollection implements ConversionExecutor {
|
||||
|
||||
private MapToStringArray converter;
|
||||
private final MapToStringArray converter;
|
||||
|
||||
private ArrayToCollection collectionConverter;
|
||||
private final ArrayToCollection collectionConverter;
|
||||
|
||||
public MapToStringCollection(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
converter = new MapToStringArray(sourceType, targetType, conversionService);
|
||||
collectionConverter = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), targetType, conversionService);
|
||||
|
||||
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 = converter.execute(map);
|
||||
return collectionConverter.execute(array);
|
||||
Object array = this.converter.execute(map);
|
||||
return this.collectionConverter.execute(array);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -20,18 +20,21 @@ 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;
|
||||
}
|
||||
|
||||
private NoOpConversionExecutor() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
|
|
@ -20,7 +21,9 @@ import org.springframework.util.NumberUtils;
|
|||
|
||||
/**
|
||||
* Converts from any JDK-standard Number implementation to a Character.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see java.lang.Character
|
||||
* @see java.lang.Short
|
||||
* @see java.lang.Integer
|
||||
|
|
@ -30,10 +33,11 @@ import org.springframework.util.NumberUtils;
|
|||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
* @since 3.0
|
||||
*/
|
||||
public class NumberToCharacter implements Converter<Number, Character> {
|
||||
|
||||
public Character convert(Number source) {
|
||||
return Character.valueOf((char) source.shortValue());
|
||||
return (char) source.shortValue();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
|
|
@ -21,10 +22,12 @@ 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
|
||||
*
|
||||
* <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
|
||||
|
|
@ -34,7 +37,6 @@ import org.springframework.util.NumberUtils;
|
|||
* @see java.lang.Double
|
||||
* @see java.math.BigDecimal
|
||||
* @see NumberUtils
|
||||
* @since 3.0
|
||||
*/
|
||||
public class NumberToNumberFactory implements ConverterFactory<Number, Number> {
|
||||
|
||||
|
|
@ -42,9 +44,10 @@ public class NumberToNumberFactory implements ConverterFactory<Number, Number> {
|
|||
return new NumberToNumber<T>(targetType);
|
||||
}
|
||||
|
||||
|
||||
private static class NumberToNumber<T extends Number> implements Converter<Number, T> {
|
||||
|
||||
private Class<T> targetType;
|
||||
private final Class<T> targetType;
|
||||
|
||||
public NumberToNumber(Class<T> targetType) {
|
||||
this.targetType = targetType;
|
||||
|
|
@ -53,6 +56,6 @@ public class NumberToNumberFactory implements ConverterFactory<Number, Number> {
|
|||
public T convert(Number source) throws Exception {
|
||||
return NumberUtils.convertNumberToTargetClass(source, targetType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -23,22 +24,26 @@ 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ObjectToArray implements ConversionExecutor {
|
||||
|
||||
private TypeDescriptor targetArrayType;
|
||||
private final TypeDescriptor targetArrayType;
|
||||
|
||||
private ConversionExecutor elementConverter;
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
|
||||
public ObjectToArray(TypeDescriptor sourceObjectType, TypeDescriptor targetArrayType,
|
||||
GenericTypeConverter conversionService) {
|
||||
GenericConversionService conversionService) {
|
||||
|
||||
this.targetArrayType = targetArrayType;
|
||||
this.elementConverter = conversionService.getConversionExecutor(sourceObjectType.getType(), TypeDescriptor.valueOf(targetArrayType.getElementType()));
|
||||
this.elementConverter = conversionService.getConversionExecutor(
|
||||
sourceObjectType.getType(), TypeDescriptor.valueOf(targetArrayType.getElementType()));
|
||||
}
|
||||
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Object array = Array.newInstance(targetArrayType.getElementType(), 1);
|
||||
Object element = elementConverter.execute(source);
|
||||
|
|
|
|||
|
|
@ -1,69 +1,58 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class ObjectToCollection implements ConversionExecutor {
|
||||
|
||||
private TypeDescriptor sourceObjectType;
|
||||
|
||||
private TypeDescriptor targetCollectionType;
|
||||
private final TypeDescriptor targetCollectionType;
|
||||
|
||||
private GenericTypeConverter typeConverter;
|
||||
|
||||
private ConversionExecutor elementConverter;
|
||||
private final ConversionExecutor elementConverter;
|
||||
|
||||
|
||||
public ObjectToCollection(TypeDescriptor sourceObjectType, TypeDescriptor targetCollectionType,
|
||||
GenericTypeConverter typeConverter) {
|
||||
this.sourceObjectType = sourceObjectType;
|
||||
GenericConversionService typeConverter) {
|
||||
|
||||
this.targetCollectionType = targetCollectionType;
|
||||
this.typeConverter = typeConverter;
|
||||
initElementConverter();
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Class implClass = ConversionUtils.getCollectionImpl(targetCollectionType.getType());
|
||||
Collection collection;
|
||||
try {
|
||||
collection = (Collection) implClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new ConversionFailedException(source, sourceObjectType.getType(), targetCollectionType.getType(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ConversionFailedException(source, sourceObjectType.getType(), targetCollectionType.getType(), e);
|
||||
}
|
||||
collection.add(elementConverter.execute(source));
|
||||
return collection;
|
||||
}
|
||||
|
||||
private void initElementConverter() {
|
||||
Class<?> elementType = targetCollectionType.getElementType();
|
||||
if (elementType != null) {
|
||||
if (elementType != null) {
|
||||
this.elementConverter = typeConverter.getConversionExecutor(sourceObjectType.getType(), TypeDescriptor.valueOf(elementType));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.elementConverter = NoOpConversionExecutor.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
Collection collection = CollectionFactory.createCollection(this.targetCollectionType.getType(), 1);
|
||||
collection.add(this.elementConverter.execute(source));
|
||||
return collection;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,35 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.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.
|
||||
* Used by the {@link DefaultConversionService} 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) {
|
||||
return source.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,31 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
|
||||
/**
|
||||
* Default conversion executor implementation for converters.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StaticConversionExecutor implements ConversionExecutor {
|
||||
|
||||
private final TypeDescriptor sourceType;
|
||||
|
|
@ -34,41 +34,44 @@ class StaticConversionExecutor implements ConversionExecutor {
|
|||
|
||||
private final Converter converter;
|
||||
|
||||
|
||||
public StaticConversionExecutor(TypeDescriptor sourceType, TypeDescriptor targetType, Converter converter) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
if (sourceType != null && !sourceType.isInstance(source)) {
|
||||
if (!this.sourceType.isInstance(source)) {
|
||||
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), "Source object "
|
||||
+ source + " to convert is expected to be an instance of [" + sourceType.getName() + "]");
|
||||
}
|
||||
try {
|
||||
return converter.convert(source);
|
||||
} catch (Exception e) {
|
||||
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), e);
|
||||
return this.converter.convert(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof StaticConversionExecutor)) {
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof StaticConversionExecutor)) {
|
||||
return false;
|
||||
}
|
||||
StaticConversionExecutor other = (StaticConversionExecutor) o;
|
||||
return sourceType.equals(other.sourceType) && targetType.equals(other.targetType);
|
||||
StaticConversionExecutor other = (StaticConversionExecutor) obj;
|
||||
return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return sourceType.hashCode() + targetType.hashCode();
|
||||
return this.sourceType.hashCode() + this.targetType.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("sourceClass", sourceType).append("targetClass", targetType)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,86 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
class StringArrayToMap implements ConversionExecutor {
|
||||
|
||||
private TypeDescriptor sourceType;
|
||||
private final TypeDescriptor sourceType;
|
||||
|
||||
private TypeDescriptor targetType;
|
||||
private final TypeDescriptor targetType;
|
||||
|
||||
private GenericTypeConverter conversionService;
|
||||
private final GenericConversionService conversionService;
|
||||
|
||||
private MapEntryConverter entryConverter;
|
||||
private final MapEntryConverter entryConverter;
|
||||
|
||||
public StringArrayToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
|
||||
public StringArrayToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
this.sourceType = sourceType;
|
||||
this.targetType = targetType;
|
||||
this.conversionService = conversionService;
|
||||
this.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()));
|
||||
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 {
|
||||
}
|
||||
else {
|
||||
return MapEntryConverter.NO_OP_INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object execute(Object source) throws ConversionFailedException {
|
||||
try {
|
||||
Map targetMap = (Map) ConversionUtils.getMapImpl(targetType.getType()).newInstance();
|
||||
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(entryConverter.convertKey(key), entryConverter.convertValue(value));
|
||||
targetMap.put(this.entryConverter.convertKey(key), this.entryConverter.convertValue(value));
|
||||
}
|
||||
return targetMap;
|
||||
} catch (Exception e) {
|
||||
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -23,6 +24,7 @@ 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
|
||||
*/
|
||||
|
|
@ -31,7 +33,7 @@ class StringCollectionToMap implements ConversionExecutor {
|
|||
|
||||
private StringArrayToMap converter;
|
||||
|
||||
public StringCollectionToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
public StringCollectionToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new StringArrayToMap(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* Converts a comma-delimited string to an array.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
|
|
@ -27,7 +29,7 @@ class StringToArray implements ConversionExecutor {
|
|||
|
||||
private ArrayToArray converter;
|
||||
|
||||
public StringToArray(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
public StringToArray(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new ArrayToArray(TypeDescriptor.valueOf(String[].class), targetType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -18,14 +18,18 @@ package org.springframework.core.convert.support;
|
|||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a BigDecimal using {@link BigDecimal#BigDecimal(String).
|
||||
* Converts a String to a BigDecimal.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBigDecimal implements Converter<String, BigDecimal> {
|
||||
|
||||
public BigDecimal convert(String source) {
|
||||
return new BigDecimal(source);
|
||||
return NumberUtils.parseNumber(source, BigDecimal.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -18,14 +18,18 @@ package org.springframework.core.convert.support;
|
|||
import java.math.BigInteger;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a BigInteger using {@link BigInteger#BigInteger(String)}.
|
||||
* Converts a String to a BigInteger.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBigInteger implements Converter<String, BigInteger> {
|
||||
|
||||
public BigInteger convert(String source) {
|
||||
return new BigInteger(source);
|
||||
return NumberUtils.parseNumber(source, BigInteger.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
|
|
@ -17,11 +17,10 @@ package org.springframework.core.convert.support;
|
|||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
|
||||
/**
|
||||
* Converts String to a Boolean. The trueString and falseStrings are configurable.
|
||||
* Converts String to a Boolean..
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @see #StringToBoolean(String, String)
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToBoolean implements Converter<String, Boolean> {
|
||||
|
|
@ -29,11 +28,13 @@ public class StringToBoolean implements Converter<String, Boolean> {
|
|||
public Boolean convert(String source) {
|
||||
if (source.equals("true")) {
|
||||
return Boolean.TRUE;
|
||||
} else if (source.equals("false")) {
|
||||
}
|
||||
else if (source.equals("false")) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid boolean string '" + source + "'; expected 'true' or 'false'");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a Byte and back.
|
||||
* Converts a String to a Byte.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToByte implements Converter<String, Byte> {
|
||||
|
||||
public Byte convert(String source) {
|
||||
return Byte.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Byte.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +1,36 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.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) {
|
||||
if (source.length() != 1) {
|
||||
throw new IllegalArgumentException("To be a Character the String '" + source + "' must have a length of 1");
|
||||
}
|
||||
return Character.valueOf(source.charAt(0));
|
||||
return source.charAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -28,7 +29,7 @@ class StringToCollection implements ConversionExecutor {
|
|||
|
||||
private ArrayToCollection converter;
|
||||
|
||||
public StringToCollection(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
public StringToCollection(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new ArrayToCollection(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -13,17 +13,22 @@
|
|||
* 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.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a Double using {@link Double#valueOf(String)}.
|
||||
* Converts a String to a Double.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToDouble implements Converter<String, Double> {
|
||||
|
||||
public Double convert(String source) {
|
||||
return Double.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Double.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
|
|
@ -21,6 +22,7 @@ import org.springframework.core.convert.converter.ConverterInfo;
|
|||
|
||||
/**
|
||||
* A factory for String to enum converters.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
|
|
@ -31,9 +33,10 @@ public class StringToEnumFactory implements ConverterFactory<String, Enum> {
|
|||
return new StringToEnum(targetType);
|
||||
}
|
||||
|
||||
class StringToEnum<T extends Enum> implements Converter<String, T>, ConverterInfo {
|
||||
|
||||
private Class<T> enumType;
|
||||
private class StringToEnum<T extends Enum> implements Converter<String, T>, ConverterInfo {
|
||||
|
||||
private final Class<T> enumType;
|
||||
|
||||
public StringToEnum(Class<T> enumType) {
|
||||
this.enumType = enumType;
|
||||
|
|
@ -44,11 +47,15 @@ public class StringToEnumFactory implements ConverterFactory<String, Enum> {
|
|||
}
|
||||
|
||||
public Class<T> getTargetType() {
|
||||
return enumType;
|
||||
return this.enumType;
|
||||
}
|
||||
|
||||
public T convert(String source) throws Exception {
|
||||
return (T) Enum.valueOf(enumType, source);
|
||||
if ("".equals(source)) {
|
||||
// It's an empty enum identifier: reset the enum value to null.
|
||||
return null;
|
||||
}
|
||||
return (T) Enum.valueOf(this.enumType, source.trim());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -13,17 +13,22 @@
|
|||
* 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.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to Float using {@link Float#valueOf(String)}.
|
||||
* Converts a String to Float.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToFloat implements Converter<String, Float> {
|
||||
|
||||
public Float convert(String source) {
|
||||
return Float.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Float.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +1,34 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to an Integer using {@link Integer#valueOf(String)}.
|
||||
* Converts a String to an Integer.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToInteger implements Converter<String, Integer> {
|
||||
|
||||
public Integer convert(String source) {
|
||||
return Integer.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Integer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.Locale;
|
||||
|
|
@ -21,12 +22,15 @@ import org.springframework.core.convert.converter.Converter;
|
|||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a Locale using {@link StringUtils#parseLocaleString(String)}.
|
||||
* Converts a String to a Locale.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToLocale implements Converter<String, Locale> {
|
||||
|
||||
public Locale convert(String source) {
|
||||
return StringUtils.parseLocaleString(source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a Long using {@link Long#valueOf(String)}.
|
||||
* Converts a String to a Long.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToLong implements Converter<String, Long> {
|
||||
|
||||
public Long convert(String source) {
|
||||
return Long.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Long.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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;
|
||||
|
|
@ -27,6 +28,7 @@ import org.springframework.core.convert.TypeDescriptor;
|
|||
* key=value
|
||||
* key=value
|
||||
* </pre>
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
|
|
@ -35,7 +37,7 @@ class StringToMap implements ConversionExecutor {
|
|||
|
||||
private StringArrayToMap converter;
|
||||
|
||||
public StringToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericTypeConverter conversionService) {
|
||||
public StringToMap(TypeDescriptor sourceType, TypeDescriptor targetType, GenericConversionService conversionService) {
|
||||
converter = new StringArrayToMap(sourceType, targetType, conversionService);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* 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.converter.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts a String to a Short using {@link Short#valueOf(String)}.
|
||||
* Converts a String to a Short.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public class StringToShort implements Converter<String, Short> {
|
||||
|
||||
public Short convert(String source) {
|
||||
return Short.valueOf(source);
|
||||
return NumberUtils.parseNumber(source, Short.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple subinterface of {@link Map} that exposes a mutex that application code can synchronize on.
|
||||
* <p>
|
||||
* Expected to be implemented by Maps that are backed by shared objects that require synchronization between multiple threads.
|
||||
* An example would be the HTTP session map.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface SharedMap<K, V> extends Map<K, V> {
|
||||
|
||||
/**
|
||||
* Returns the shared mutex that may be synchronized on using a synchronized block. The returned mutex is guaranteed
|
||||
* to be non-null.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* <pre>
|
||||
* synchronized (sharedMap.getMutex()) {
|
||||
* // do synchronized work
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @return the mutex
|
||||
*/
|
||||
public Object getMutex();
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
|
||||
/**
|
||||
* A map decorator that implements <code>SharedMap</code>.
|
||||
* By default, simply returns the map itself as the mutex.
|
||||
* Subclasses may override to return a different mutex object.
|
||||
* @author Keith Donald
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SharedMapDecorator<K, V> implements SharedMap<K, V>, Serializable {
|
||||
|
||||
/**
|
||||
* The wrapped, target map.
|
||||
*/
|
||||
private Map<K, V> map;
|
||||
|
||||
/**
|
||||
* Creates a new shared map decorator.
|
||||
* @param map the map that is shared by multiple threads, to be synced
|
||||
*/
|
||||
public SharedMapDecorator(Map<K, V> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
// implementing Map
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
public Set<Map.Entry<K, V>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> map) {
|
||||
this.map.putAll(map);
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
return map.remove(key);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public Collection<V> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
// implementing SharedMap
|
||||
|
||||
public Object getMutex() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("map", map).append("mutex", getMutex()).toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -35,6 +35,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
|
||||
private Set<Map.Entry<String, V>> entrySet;
|
||||
|
||||
|
||||
// implementing Map
|
||||
|
||||
public void clear() {
|
||||
|
|
@ -109,6 +110,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
return (values != null) ? values : (values = new Values());
|
||||
}
|
||||
|
||||
|
||||
// hook methods
|
||||
|
||||
/**
|
||||
|
|
@ -140,6 +142,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
*/
|
||||
protected abstract Iterator<String> getAttributeNames();
|
||||
|
||||
|
||||
// internal helper classes
|
||||
|
||||
private class KeySet extends AbstractSet<String> {
|
||||
|
|
@ -167,9 +170,9 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
public boolean remove(Object o) {
|
||||
return StringKeyedMapAdapter.this.remove(o) != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class KeyIterator implements Iterator<String> {
|
||||
|
||||
private final Iterator<String> it = getAttributeNames();
|
||||
|
|
@ -190,9 +193,9 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
}
|
||||
StringKeyedMapAdapter.this.remove(currentKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class Values extends AbstractSet<V> {
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
|
@ -229,6 +232,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class ValuesIterator implements Iterator<V> {
|
||||
|
||||
private final Iterator<String> it = getAttributeNames();
|
||||
|
|
@ -250,9 +254,9 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
}
|
||||
StringKeyedMapAdapter.this.remove(currentKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class EntrySet extends AbstractSet<Map.Entry<String, V>> {
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
|
@ -300,6 +304,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private class EntryIterator implements Iterator<Map.Entry<String, V>> {
|
||||
|
||||
private final Iterator<String> it = getAttributeNames();
|
||||
|
|
@ -324,6 +329,7 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
|
||||
}
|
||||
|
||||
|
||||
private class EntrySetEntry implements Entry<String, V> {
|
||||
|
||||
private final String currentKey;
|
||||
|
|
@ -344,4 +350,5 @@ public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
|
|||
return StringKeyedMapAdapter.this.put(currentKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,39 @@
|
|||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.ArrayToArray;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ArrayToArrayTests {
|
||||
|
||||
@Test
|
||||
public void testArrayToArrayConversion() {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToArray c = new ArrayToArray(TypeDescriptor.valueOf(String[].class), TypeDescriptor.valueOf(Integer[].class), service);
|
||||
Integer[] result = (Integer[]) c.execute(new String[] { "1", "2", "3" });
|
||||
assertEquals(new Integer(1), result[0]);
|
||||
assertEquals(new Integer(2), result[1]);
|
||||
assertEquals(new Integer(3), result[2]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
package org.springframework.core.convert.support;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
|
@ -8,26 +22,30 @@ 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;
|
||||
import org.springframework.core.convert.support.ArrayToCollection;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ArrayToCollectionTests {
|
||||
|
||||
@Test
|
||||
public void testArrayToCollectionConversion() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
ArrayToCollection c = new ArrayToCollection(TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getField("bindTarget")), service);
|
||||
List result = (List) c.execute(new String[] { "1", "2", "3" });
|
||||
assertEquals(new Integer(1), result.get(0));
|
||||
assertEquals(new Integer(2), result.get(1));
|
||||
assertEquals(new Integer(3), result.get(2));
|
||||
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 {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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());
|
||||
|
|
@ -35,7 +53,7 @@ public class ArrayToCollectionTests {
|
|||
|
||||
@Test
|
||||
public void testArrayToSortedSetConversion() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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());
|
||||
|
|
@ -43,7 +61,7 @@ public class ArrayToCollectionTests {
|
|||
|
||||
@Test
|
||||
public void testArrayToCollectionImplConversion() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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());
|
||||
|
|
@ -51,7 +69,7 @@ public class ArrayToCollectionTests {
|
|||
|
||||
@Test
|
||||
public void testArrayToNonGenericCollectionConversionNullElement() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -1,20 +1,37 @@
|
|||
package org.springframework.core.convert.support;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
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;
|
||||
import org.springframework.core.convert.support.CollectionToArray;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CollectionToArrayTests {
|
||||
|
||||
@Test
|
||||
public void testCollectionToArrayConversion() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(new TypeDescriptor(getClass().getField("bindTarget")),
|
||||
TypeDescriptor.valueOf(Integer[].class), service);
|
||||
bindTarget.add("1");
|
||||
|
|
@ -28,7 +45,7 @@ public class CollectionToArrayTests {
|
|||
|
||||
@Test
|
||||
public void testCollectionToArrayConversionNoGenericInfo() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
|
||||
.valueOf(Integer[].class), service);
|
||||
bindTarget.add("1");
|
||||
|
|
@ -42,7 +59,7 @@ public class CollectionToArrayTests {
|
|||
|
||||
@Test
|
||||
public void testCollectionToArrayConversionNoGenericInfoNullElement() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToArray c = new CollectionToArray(TypeDescriptor.valueOf(Collection.class), TypeDescriptor
|
||||
.valueOf(Integer[].class), service);
|
||||
bindTarget.add(null);
|
||||
|
|
|
|||
|
|
@ -1,85 +1,104 @@
|
|||
package org.springframework.core.convert.support;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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;
|
||||
import org.springframework.core.convert.support.CollectionToCollection;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CollectionToCollectionTests {
|
||||
|
||||
@Test
|
||||
public void testCollectionToCollectionConversion() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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");
|
||||
List result = (List) c.execute(bindTarget);
|
||||
assertEquals(new Integer(1), result.get(0));
|
||||
assertEquals(new Integer(2), result.get(1));
|
||||
assertEquals(new Integer(3), result.get(2));
|
||||
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 {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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");
|
||||
List result = (List) c.execute(bindTarget);
|
||||
assertEquals("1", result.get(0));
|
||||
assertEquals("2", result.get(1));
|
||||
assertEquals("3", result.get(2));
|
||||
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 {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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");
|
||||
List result = (List) c.execute(bindTarget);
|
||||
assertEquals(new Integer(1), result.get(0));
|
||||
assertEquals(new Integer(2), result.get(1));
|
||||
assertEquals(new Integer(3), result.get(2));
|
||||
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 testCollectionToCollectionConversionNoGenericInfoSourceNullValues() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
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(null);
|
||||
bindTarget.add("3");
|
||||
List result = (List) c.execute(bindTarget);
|
||||
assertEquals(null, result.get(0));
|
||||
assertEquals(new Integer(1), result.get(1));
|
||||
assertEquals(new Integer(2), result.get(2));
|
||||
assertEquals(null, result.get(3));
|
||||
assertEquals(new Integer(3), result.get(4));
|
||||
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 {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
CollectionToCollection c = new CollectionToCollection(TypeDescriptor.valueOf(Collection.class),
|
||||
new TypeDescriptor(getClass().getField("integerTarget")), service);
|
||||
List result = (List) c.execute(bindTarget);
|
||||
Collection result = (Collection) c.execute(bindTarget);
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
|
|
@ -87,5 +106,4 @@ public class CollectionToCollectionTests {
|
|||
public Collection<String> bindTarget = new ArrayList<String>();
|
||||
public List<Integer> integerTarget = new ArrayList<Integer>();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* 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;
|
||||
|
|
@ -27,8 +43,10 @@ import org.springframework.core.convert.support.StringToShort;
|
|||
|
||||
/**
|
||||
* Tests for the default converters in the converters package.
|
||||
s */
|
||||
public class DefaultTypeConverterTests {
|
||||
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class DefaultConversionServiceTests {
|
||||
|
||||
@Test
|
||||
public void testStringToByte() throws Exception {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* 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.
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
|
@ -32,9 +33,12 @@ import org.springframework.core.convert.ConverterNotFoundException;
|
|||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
public class GenericTypeConverterTests {
|
||||
/**
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class GenericConversionServiceTests {
|
||||
|
||||
private GenericTypeConverter converter = new GenericTypeConverter();
|
||||
private GenericConversionService converter = new GenericConversionService();
|
||||
|
||||
@Test
|
||||
public void executeConversion() {
|
||||
|
|
@ -151,7 +155,7 @@ public class GenericTypeConverterTests {
|
|||
@Test
|
||||
public void convertArrayToListGenericTypeConversion() throws Exception {
|
||||
converter.add(new StringToInteger());
|
||||
List<Integer> result = converter.convert(new String[] { "1", "2", "3" }, new TypeDescriptor<List<Integer>>(getClass().getDeclaredField("genericList")));
|
||||
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));
|
||||
assertEquals(new Integer("3"), result.get(2));
|
||||
|
|
@ -208,7 +212,7 @@ public class GenericTypeConverterTests {
|
|||
foo.put("2", "BAZ");
|
||||
converter.add(new StringToInteger());
|
||||
converter.add(new StringToEnumFactory().getConverter(FooEnum.class));
|
||||
Map<String, FooEnum> map = converter.convert(foo, new TypeDescriptor<Map<String, FooEnum>>(getClass().getField("genericMap")));
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
* 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;
|
||||
|
|
@ -7,16 +23,19 @@ import java.util.Map;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultTypeConverter;
|
||||
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 {
|
||||
DefaultTypeConverter converter = new DefaultTypeConverter();
|
||||
MapToMap c = new MapToMap(new TypeDescriptor<Map<String, String>>(getClass().getField("source")),
|
||||
new TypeDescriptor<Map<String, FooEnum>>(getClass().getField("bindTarget")), converter);
|
||||
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);
|
||||
|
|
@ -26,7 +45,7 @@ public class MapToMapTests {
|
|||
|
||||
@Test
|
||||
public void testMapToMapConversionNoGenericInfoOnSource() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
MapToMap c = new MapToMap(TypeDescriptor.valueOf(Map.class),
|
||||
new TypeDescriptor(getClass().getField("bindTarget")), service);
|
||||
source.put("1", "BAR");
|
||||
|
|
@ -38,7 +57,7 @@ public class MapToMapTests {
|
|||
|
||||
@Test
|
||||
public void testMapToMapConversionNoGenericInfo() throws Exception {
|
||||
DefaultTypeConverter service = new DefaultTypeConverter();
|
||||
DefaultConversionService service = new DefaultConversionService();
|
||||
MapToMap c = new MapToMap(TypeDescriptor.valueOf(Map.class),
|
||||
TypeDescriptor.valueOf(Map.class), service);
|
||||
source.put("1", "BAR");
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
package org.springframework.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.springframework.binding.collection.SharedMapDecorator}.
|
||||
*/
|
||||
public class SharedMapDecoratorTests extends TestCase {
|
||||
|
||||
private SharedMapDecorator map = new SharedMapDecorator(new HashMap());
|
||||
|
||||
public void testGetPutRemove() {
|
||||
assertTrue(map.size() == 0);
|
||||
assertTrue(map.isEmpty());
|
||||
assertNull(map.get("foo"));
|
||||
assertFalse(map.containsKey("foo"));
|
||||
map.put("foo", "bar");
|
||||
assertTrue(map.size() == 1);
|
||||
assertFalse(map.isEmpty());
|
||||
assertNotNull(map.get("foo"));
|
||||
assertTrue(map.containsKey("foo"));
|
||||
assertTrue(map.containsValue("bar"));
|
||||
assertEquals("bar", map.get("foo"));
|
||||
map.remove("foo");
|
||||
assertTrue(map.size() == 0);
|
||||
assertNull(map.get("foo"));
|
||||
}
|
||||
|
||||
public void testPutAll() {
|
||||
Map all = new HashMap();
|
||||
all.put("foo", "bar");
|
||||
all.put("bar", "baz");
|
||||
map.putAll(all);
|
||||
assertTrue(map.size() == 2);
|
||||
}
|
||||
|
||||
public void testEntrySet() {
|
||||
map.put("foo", "bar");
|
||||
map.put("bar", "baz");
|
||||
Set entrySet = map.entrySet();
|
||||
assertTrue(entrySet.size() == 2);
|
||||
}
|
||||
|
||||
public void testKeySet() {
|
||||
map.put("foo", "bar");
|
||||
map.put("bar", "baz");
|
||||
Set keySet = map.keySet();
|
||||
assertTrue(keySet.size() == 2);
|
||||
}
|
||||
|
||||
public void testValues() {
|
||||
map.put("foo", "bar");
|
||||
map.put("bar", "baz");
|
||||
Collection values = map.values();
|
||||
assertTrue(values.size() == 2);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue