revised default converters; renamed ConverterRegistry's addGenericConverter to addConverter

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2658 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Juergen Hoeller 2009-12-14 21:14:26 +00:00
parent e77354546e
commit 18ec90aff9
29 changed files with 208 additions and 776 deletions

View File

@ -45,13 +45,13 @@ import org.springframework.format.Printer;
public class FormattingConversionService extends GenericConversionService implements FormatterRegistry {
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) {
addGenericConverter(new PrinterConverter(fieldType, formatter, this));
addGenericConverter(new ParserConverter(fieldType, formatter, this));
addConverter(new PrinterConverter(fieldType, formatter, this));
addConverter(new ParserConverter(fieldType, formatter, this));
}
public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) {
addGenericConverter(new PrinterConverter(fieldType, printer, this));
addGenericConverter(new ParserConverter(fieldType, parser, this));
addConverter(new PrinterConverter(fieldType, printer, this));
addConverter(new ParserConverter(fieldType, parser, this));
}
@SuppressWarnings("unchecked")
@ -67,7 +67,7 @@ public class FormattingConversionService extends GenericConversionService implem
Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes();
for (final Class<?> fieldType : fieldTypes) {
addGenericConverter(new ConditionalGenericConverter() {
addConverter(new ConditionalGenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(fieldType, String.class));
}
@ -83,7 +83,7 @@ public class FormattingConversionService extends GenericConversionService implem
String.class.getName() + ": " + annotationFormatterFactory;
}
});
addGenericConverter(new ConditionalGenericConverter() {
addConverter(new ConditionalGenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, fieldType));
}

View File

@ -381,7 +381,8 @@ public class TypeDescriptor {
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) {

View File

@ -20,12 +20,18 @@ package org.springframework.core.convert.converter;
* For registering converters with a type conversion system.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
public interface ConverterRegistry {
/**
* Add a converter to this registry.
* Add a generic converter to this registry.
*/
void addConverter(GenericConverter converter);
/**
* Add a plain converter to this registry.
*/
void addConverter(Converter<?, ?> converter);
@ -34,11 +40,6 @@ public interface ConverterRegistry {
*/
void addConverterFactory(ConverterFactory<?, ?> converterFactory);
/**
* Add a generic converter to this registry.
*/
void addGenericConverter(GenericConverter converter);
/**
* Remove any converters from sourceType to targetType.
* @param sourceType the source type

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Collections;
@ -31,9 +29,11 @@ import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts an Array to a Collection.
* First, creates a new Collection of the requested targetType.
*
* <p>First, creates a new Collection of the requested targetType.
* Then adds each array element to the target collection.
* Will perform an element conversion from the source component type to the collection's parameterized type if necessary.
* Will perform an element conversion from the source component type
* to the collection's parameterized type if necessary.
*
* @author Keith Donald
* @since 3.0
@ -75,7 +75,8 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
}
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetElementType);
Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceElementType, targetElementType);
collection.add(targetElement);
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.ObjectUtils;
/**
* Converts an Array to a Map.
* First adapts the source Array to a List, then delegates to {@link CollectionToMapConverter} to perform the target Map conversion.
*
* @author Keith Donald
* @since 3.0
*/
final class ArrayToMapConverter implements ConditionalGenericConverter {
private final CollectionToMapConverter helperConverter;
public ArrayToMapConverter(GenericConversionService conversionService) {
this.helperConverter = new CollectionToMapConverter(conversionService);
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object[].class, Map.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.matches(sourceType, targetType);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.convert(Arrays.asList(ObjectUtils.toObjectArray(source)), sourceType, targetType);
}
}

View File

@ -16,9 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Collections;
@ -31,11 +28,13 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter;
/**
* Converts a Collection to an Array.
* First, creates a new Array of the requested targetType with a length equal to the size of the source Collection.
* Then sets each collection element into the array.
* Will perform an element conversion from the collection's parameterized type to the array's component type if necessary.
*
* Converts a Collection to an array.
*
* <p>First, creates a new array of the requested targetType with a length equal to the
* size of the source Collection. Then sets each collection element into the array.
* Will perform an element conversion from the collection's parameterized type to the
* array's component type if necessary.
*
* @author Keith Donald
* @since 3.0
*/
@ -62,7 +61,7 @@ final class CollectionToArrayConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source;
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection);
sourceElementType = ConversionUtils.getElementType(sourceCollection);
}
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
Object array = Array.newInstance(targetElementType.getType(), sourceCollection.size());
@ -79,7 +78,8 @@ final class CollectionToArrayConverter implements ConditionalGenericConverter {
}
for (Iterator<?> it = sourceCollection.iterator(); it.hasNext(); i++) {
Object sourceElement = it.next();
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetElementType);
Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceElementType, targetElementType);
Array.set(array, i, targetElement);
}
}

View File

@ -25,13 +25,14 @@ import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter;
import static org.springframework.core.convert.support.ConversionUtils.*;
/**
* Converts from a Collection to another Collection.
* First, creates a new Collection of the requested targetType with a size equal to the size of the source Collection.
* Then copies each element in the source collection to the target collection.
* Will perform an element conversion from the source collection's parameterized type to the target collection's parameterized type if necessary.
*
* <p>First, creates a new Collection of the requested targetType with a size equal to the
* size of the source Collection. Then copies each element in the source collection to the
* target collection. Will perform an element conversion from the source collection's
* parameterized type to the target collection's parameterized type if necessary.
*
* @author Keith Donald
* @since 3.0
@ -60,14 +61,15 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert
Collection<?> sourceCollection = (Collection<?>) source;
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection);
sourceElementType = ConversionUtils.getElementType(sourceCollection);
}
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL || targetElementType == TypeDescriptor.NULL
|| sourceElementType.isAssignableTo(targetElementType)) {
if (sourceType.isAssignableTo(targetType)) {
return sourceCollection;
} else {
}
else {
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
target.addAll(sourceCollection);
return target;
@ -79,7 +81,7 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert
throw new ConverterNotFoundException(sourceElementType, targetElementType);
}
for (Object element : sourceCollection) {
target.add(invokeConverter(converter, element, sourceElementType, targetElementType));
target.add(ConversionUtils.invokeConverter(converter, element, sourceElementType, targetElementType));
}
return target;
}

View File

@ -1,125 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts a Collection to a Map.
* First, creates a new Map of the requested targetType with a size equal to the size of the source Collection.
* Then copies each element in the source collection to the target map.
* During the copy process, if an element is a String, that String is treated as a "key=value" pair, parsed, and a corresponding entry is created in the target map.
* If an element is another Object type, an entry is created in the targetMap with this Object as both the key and value.
* Will perform an element conversion from the source collection's parameterized type to the target map's parameterized K,V types if necessary.
*
* @author Keith Donald
* @since 3.0
*/
final class CollectionToMapConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public CollectionToMapConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Collection.class, Map.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getMapKeyTypeDescriptor()) &&
this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getMapValueTypeDescriptor());
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Collection<?> sourceCollection = (Collection<?>) source;
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection);
}
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
boolean keysCompatible = false;
if (sourceElementType != TypeDescriptor.NULL && sourceElementType.isAssignableTo(targetKeyType)) {
keysCompatible = true;
}
boolean valuesCompatible = false;
if (sourceElementType != TypeDescriptor.NULL && sourceElementType.isAssignableTo(targetValueType)) {
valuesCompatible = true;
}
if (keysCompatible && valuesCompatible) {
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size());
if (String.class.equals(sourceElementType.getType())) {
for (Object element : sourceCollection) {
String[] property = parseProperty((String) element);
target.put(property[0], property[1]);
}
}
else {
for (Object element : sourceCollection) {
target.put(element, element);
}
}
return target;
}
else {
Map target = CollectionFactory.createMap(targetType.getType(), sourceCollection.size());
MapEntryConverter converter = new MapEntryConverter(sourceElementType, sourceElementType, targetKeyType,
targetValueType, keysCompatible, valuesCompatible, this.conversionService);
if (String.class.equals(sourceElementType.getType())) {
for (Object element : sourceCollection) {
String[] property = parseProperty((String) element);
Object targetKey = converter.convertKey(property[0]);
Object targetValue = converter.convertValue(property[1]);
target.put(targetKey, targetValue);
}
}
else {
for (Object element : sourceCollection) {
Object targetKey = converter.convertKey(element);
Object targetValue = converter.convertValue(element);
target.put(targetKey, targetValue);
}
}
return target;
}
}
private String[] parseProperty(String string) {
String[] property = string.split("=");
if (property.length < 2) {
throw new IllegalArgumentException("Invalid String property '" + string +
"'; properties should be in the format name=value");
}
return property;
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@ -56,7 +54,8 @@ final class CollectionToObjectConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.size() == 0) {
return null;
} else {
}
else {
Object firstElement = sourceCollection.iterator().next();
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL && firstElement != null) {
@ -64,12 +63,13 @@ final class CollectionToObjectConverter implements ConditionalGenericConverter {
}
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
return firstElement;
} else {
}
else {
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
if (converter == null) {
throw new ConverterNotFoundException(sourceElementType, targetType);
}
return invokeConverter(converter, firstElement, sourceElementType, targetType);
return ConversionUtils.invokeConverter(converter, firstElement, sourceElementType, targetType);
}
}
}

View File

@ -16,9 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getElementType;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@ -59,10 +56,11 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.size() == 0) {
return "";
} else {
}
else {
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection);
sourceElementType = ConversionUtils.getElementType(sourceCollection);
}
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
StringBuilder string = new StringBuilder();
@ -75,7 +73,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
i++;
}
return string.toString();
} else {
}
else {
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
if (converter == null) {
throw new ConverterNotFoundException(sourceElementType, targetType);
@ -86,7 +85,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
if (i > 0) {
string.append(DELIMITER);
}
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetType);
Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceElementType, targetType);
string.append(targetElement);
i++;
}
@ -94,4 +94,5 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
}
}
}
}

View File

@ -46,27 +46,21 @@ public abstract class ConversionServiceFactory {
* Populate the given ConversionService instance with all applicable default converters.
*/
public static void addDefaultConverters(GenericConversionService conversionService) {
conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService));
conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService));
conversionService.addGenericConverter(new ArrayToMapConverter(conversionService));
conversionService.addGenericConverter(new ArrayToStringConverter(conversionService));
conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService));
conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService));
conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService));
conversionService.addGenericConverter(new CollectionToMapConverter(conversionService));
conversionService.addGenericConverter(new CollectionToStringConverter(conversionService));
conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService));
conversionService.addGenericConverter(new MapToMapConverter(conversionService));
conversionService.addGenericConverter(new MapToArrayConverter(conversionService));
conversionService.addGenericConverter(new MapToCollectionConverter(conversionService));
conversionService.addGenericConverter(new MapToStringConverter(conversionService));
conversionService.addGenericConverter(new MapToObjectConverter(conversionService));
conversionService.addGenericConverter(new StringToArrayConverter(conversionService));
conversionService.addGenericConverter(new StringToCollectionConverter(conversionService));
conversionService.addGenericConverter(new StringToMapConverter(conversionService));
conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService));
conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService));
conversionService.addGenericConverter(new ObjectToMapConverter(conversionService));
conversionService.addConverter(new ArrayToArrayConverter(conversionService));
conversionService.addConverter(new ArrayToCollectionConverter(conversionService));
conversionService.addConverter(new ArrayToStringConverter(conversionService));
conversionService.addConverter(new ArrayToObjectConverter(conversionService));
conversionService.addConverter(new CollectionToCollectionConverter(conversionService));
conversionService.addConverter(new CollectionToArrayConverter(conversionService));
conversionService.addConverter(new CollectionToStringConverter(conversionService));
conversionService.addConverter(new CollectionToObjectConverter(conversionService));
conversionService.addConverter(new MapToMapConverter(conversionService));
conversionService.addConverter(new PropertiesToStringConverter(conversionService));
conversionService.addConverter(new StringToArrayConverter(conversionService));
conversionService.addConverter(new StringToCollectionConverter(conversionService));
conversionService.addConverter(new StringToPropertiesConverter(conversionService));
conversionService.addConverter(new ObjectToArrayConverter(conversionService));
conversionService.addConverter(new ObjectToCollectionConverter(conversionService));
conversionService.addConverterFactory(new CharacterToNumberFactory());
conversionService.addConverter(new NumberToCharacterConverter());
conversionService.addConverterFactory(new NumberToNumberConverterFactory());
@ -76,8 +70,8 @@ public abstract class ConversionServiceFactory {
conversionService.addConverter(new StringToLocaleConverter());
conversionService.addConverterFactory(new StringToNumberConverterFactory());
conversionService.addConverter(new ObjectToStringConverter());
conversionService.addGenericConverter(new ObjectToObjectGenericConverter());
conversionService.addGenericConverter(new IdToEntityConverter(conversionService));
conversionService.addConverter(new ObjectToObjectConverter());
conversionService.addConverter(new IdToEntityConverter(conversionService));
}
/**
@ -89,15 +83,15 @@ public abstract class ConversionServiceFactory {
public static void registerConverters(Set<Object> converters, ConverterRegistry registry) {
if (converters != null) {
for (Object converter : converters) {
if (converter instanceof Converter<?, ?>) {
if (converter instanceof GenericConverter) {
registry.addConverter((GenericConverter) converter);
}
else if (converter instanceof Converter<?, ?>) {
registry.addConverter((Converter<?, ?>) converter);
}
else if (converter instanceof ConverterFactory<?, ?>) {
registry.addConverterFactory((ConverterFactory<?, ?>) converter);
}
else if (converter instanceof GenericConverter) {
registry.addGenericConverter((GenericConverter) converter);
}
else {
throw new IllegalArgumentException("Each converter object must implement one of the " +
"Converter, ConverterFactory, or GenericConverter interfaces");

View File

@ -39,7 +39,6 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.core.convert.converter.GenericConverter;
import static org.springframework.core.convert.support.ConversionUtils.*;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -71,13 +70,20 @@ public class GenericConversionService implements ConversionService, ConverterReg
// implementing ConverterRegistry
public void addConverter(GenericConverter converter) {
Set<GenericConverter.ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
for (GenericConverter.ConvertiblePair convertibleType : convertibleTypes) {
getMatchableConvertersList(convertibleType.getSourceType(), convertibleType.getTargetType()).add(converter);
}
}
public void addConverter(Converter<?, ?> converter) {
GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class);
if (typeInfo == null) {
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> which " +
"your Converter<S, T> converts between; declare these generic types.");
}
addGenericConverter(new ConverterAdapter(typeInfo, converter));
addConverter(new ConverterAdapter(typeInfo, converter));
}
public void addConverterFactory(ConverterFactory<?, ?> converterFactory) {
@ -86,14 +92,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetRangeType R which " +
"your ConverterFactory<S, R> converts between; declare these generic types.");
}
addGenericConverter(new ConverterFactoryAdapter(typeInfo, converterFactory));
}
public void addGenericConverter(GenericConverter converter) {
Set<GenericConverter.ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
for (GenericConverter.ConvertiblePair convertibleType : convertibleTypes) {
getMatchableConvertersList(convertibleType.getSourceType(), convertibleType.getTargetType()).add(converter);
}
addConverter(new ConverterFactoryAdapter(typeInfo, converterFactory));
}
public void removeConvertible(Class<?> sourceType, Class<?> targetType) {
@ -133,7 +132,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetType);
}
return invokeConverter(converter, source, sourceType, targetType);
return ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
}
public String toString() {
@ -368,7 +367,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
return (matchable != null ? matchable.matchConverter(sourceFieldType, targetFieldType) : null);
}
@SuppressWarnings("unchecked")
private final class ConverterAdapter implements GenericConverter {

View File

@ -38,7 +38,7 @@ import org.springframework.util.ReflectionUtils;
*/
final class IdToEntityConverter implements ConditionalGenericConverter {
private GenericConversionService conversionService;
private final GenericConversionService conversionService;
public IdToEntityConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
@ -50,7 +50,8 @@ final class IdToEntityConverter implements ConditionalGenericConverter {
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
Method finder = getFinder(targetType.getType());
return finder != null && this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
return (finder != null &&
this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])));
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -58,7 +59,8 @@ final class IdToEntityConverter implements ConditionalGenericConverter {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Method finder = getFinder(targetType.getType());
Object id = this.conversionService.convert(source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
Object id = this.conversionService.convert(
source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]));
return ReflectionUtils.invokeMethod(finder, source, id);
}
@ -66,7 +68,8 @@ final class IdToEntityConverter implements ConditionalGenericConverter {
String finderMethod = "find" + getEntityName(entityClass);
Method[] methods = entityClass.getDeclaredMethods();
for (Method method : methods) {
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass)) {
if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1 &&
method.getReturnType().equals(entityClass)) {
if (method.getName().equals(finderMethod)) {
return method;
}
@ -80,7 +83,8 @@ final class IdToEntityConverter implements ConditionalGenericConverter {
int lastDot = shortName.lastIndexOf('.');
if (lastDot != -1) {
return shortName.substring(lastDot + 1);
} else {
}
else {
return shortName;
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
@ -45,6 +43,7 @@ class MapEntryConverter {
public MapEntryConverter(TypeDescriptor sourceKeyType, TypeDescriptor sourceValueType,
TypeDescriptor targetKeyType, TypeDescriptor targetValueType, boolean keysCompatible,
boolean valuesCompatible, GenericConversionService conversionService) {
if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL && !keysCompatible) {
this.keyConverter = conversionService.getConverter(sourceKeyType, targetKeyType);
if (this.keyConverter == null) {
@ -53,6 +52,7 @@ class MapEntryConverter {
this.sourceKeyType = sourceKeyType;
this.targetKeyType = targetKeyType;
}
if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL && !valuesCompatible) {
this.valueConverter = conversionService.getConverter(sourceValueType, targetValueType);
if (this.valueConverter == null) {
@ -65,16 +65,20 @@ class MapEntryConverter {
public Object convertKey(Object sourceKey) {
if (sourceKey != null && this.keyConverter != null) {
return invokeConverter(this.keyConverter, sourceKey, this.sourceKeyType, this.targetKeyType);
} else {
return ConversionUtils.invokeConverter(
this.keyConverter, sourceKey, this.sourceKeyType, this.targetKeyType);
}
else {
return sourceKey;
}
}
public Object convertValue(Object sourceValue) {
if (sourceValue != null && this.valueConverter != null) {
return invokeConverter(this.valueConverter, sourceValue, this.sourceValueType, this.targetValueType);
} else {
return ConversionUtils.invokeConverter(
this.valueConverter, sourceValue, this.sourceValueType, this.targetValueType);
}
else {
return sourceValue;
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts a Map to an Array.
* First converts the source Map to a Collection, then converts that Collection to an Array.
* Delegates to {@link MapToCollectionConverter} and {@link CollectionToArrayConverter} helpers to do this.
*
* @author Keith Donald
* @since 3.0
*/
final class MapToArrayConverter implements ConditionalGenericConverter {
private final MapToCollectionConverter mapToCollectionHelperConverter;
private final CollectionToArrayConverter collectionToArrayHelperConverter;
public MapToArrayConverter(GenericConversionService conversionService) {
this.mapToCollectionHelperConverter = new MapToCollectionConverter(conversionService);
this.collectionToArrayHelperConverter = new CollectionToArrayConverter(conversionService);
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Map.class, Object[].class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.mapToCollectionHelperConverter.matches(sourceType, targetType);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
TypeDescriptor collectionType = TypeDescriptor.collection(List.class, targetType.getElementTypeDescriptor());
Object collection = this.mapToCollectionHelperConverter.convert(source, sourceType, collectionType);
return this.collectionToArrayHelperConverter.convert(collection, collectionType, targetType);
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts a Map to a Collection.
* First, creates a new Collection of the requested targetType with a size equal to the size of the source Map.
* Then copies each element in the source map to the target collection.
* During the copy process, if the target collection's parameterized type is a String, each Map entry is first encoded as a "key=value" property String, then added to the Collection.
* If the collection type is another Object type, the value of each Map entry is added to the Collection.
* Will perform a conversion from the source maps's parameterized K,V types to the target collection's parameterized type if necessary.
*
* @author Keith Donald
* @since 3.0
*/
final class MapToCollectionConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public MapToCollectionConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Map.class, Collection.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
if (String.class.equals(targetType.getType())) {
return this.conversionService.canConvert(sourceType.getMapKeyTypeDescriptor(), targetType.getElementTypeDescriptor()) &&
this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType.getElementTypeDescriptor());
} else {
return this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType.getElementTypeDescriptor());
}
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Map<?, ?> sourceMap = (Map<?, ?>) source;
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1];
}
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
boolean keysCompatible = false;
if (sourceKeyType != TypeDescriptor.NULL && sourceKeyType.isAssignableTo(targetElementType)) {
keysCompatible = true;
}
boolean valuesCompatible = false;
if (sourceValueType != TypeDescriptor.NULL || sourceValueType.isAssignableTo(targetElementType)) {
valuesCompatible = true;
}
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceMap.size());
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetElementType,
targetElementType, keysCompatible, valuesCompatible, this.conversionService);
if (String.class.equals(targetElementType.getType())) {
for (Object entry : sourceMap.entrySet()) {
Map.Entry<?, ?> mapEntry = (Map.Entry<?, ?>) entry;
String property = converter.convertKey(mapEntry.getKey()) + "="
+ converter.convertValue(mapEntry.getValue());
target.add(property);
}
} else {
for (Object value : sourceMap.values()) {
target.add(converter.convertValue(value));
}
}
return target;
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@ -28,9 +26,11 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts a Map to another Map.
* First, creates a new Map of the requested targetType with a size equal to the size of the source Map.
* Then copies each element in the source map to the target map.
* Will perform a conversion from the source maps's parameterized K,V types to the target map's parameterized types K,V if necessary.
*
* <p>First, creates a new Map of the requested targetType with a size equal to the
* size of the source Map. Then copies each element in the source map to the target map.
* Will perform a conversion from the source maps's parameterized K,V types to the target
* map's parameterized types K,V if necessary.
*
* @author Keith Donald
* @since 3.0
@ -66,7 +66,7 @@ final class MapToMapConverter implements ConditionalGenericConverter {
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap);
TypeDescriptor[] sourceEntryTypes = ConversionUtils.getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1];
}
@ -98,9 +98,10 @@ final class MapToMapConverter implements ConditionalGenericConverter {
@SuppressWarnings("unchecked")
private Map<?, ?> compatibleMapWithoutEntryConversion(Map<?, ?> source, TypeDescriptor targetType) {
if (targetType.getType().isAssignableFrom(source.getClass())) {
if (targetType.getType().isInstance(source)) {
return source;
} else {
}
else {
Map target = CollectionFactory.createMap(targetType.getType(), source.size());
target.putAll(source);
return target;

View File

@ -1,71 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts a Map to an Object by returning the first Map entry value after converting it to the desired targetType.
*
* @author Keith Donald
* @since 3.0
*/
final class MapToObjectConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public MapToObjectConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Map.class, Object.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Map<?, ?> sourceMap = (Map<?, ?>) source;
if (sourceMap.size() == 0) {
return null;
} else {
Object firstValue = sourceMap.values().iterator().next();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceValueType == TypeDescriptor.NULL) {
sourceValueType = TypeDescriptor.forObject(firstValue);
}
boolean valuesCompatible = false;
if (sourceValueType != TypeDescriptor.NULL && sourceValueType.isAssignableTo(targetType)) {
valuesCompatible = true;
}
MapEntryConverter converter = new MapEntryConverter(sourceValueType, sourceValueType, targetType,
targetType, true, valuesCompatible, this.conversionService);
return converter.convertValue(firstValue);
}
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Set;
@ -58,12 +56,13 @@ final class ObjectToArrayConverter implements ConditionalGenericConverter {
Object target = Array.newInstance(targetElementType.getType(), 1);
if (sourceType.isAssignableTo(targetElementType)) {
Array.set(target, 0, source);
} else {
}
else {
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetElementType);
}
Array.set(target, 0, invokeConverter(converter, source, sourceType, targetElementType));
Array.set(target, 0, ConversionUtils.invokeConverter(converter, source, sourceType, targetElementType));
}
return target;
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@ -60,12 +58,13 @@ final class ObjectToCollectionConverter implements ConditionalGenericConverter {
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
target.add(source);
} else {
}
else {
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetElementType);
}
target.add(invokeConverter(converter, source, sourceType, targetElementType));
target.add(ConversionUtils.invokeConverter(converter, source, sourceType, targetElementType));
}
return target;
}

View File

@ -1,76 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Converts an Object to a single-entry Map containing the Object.
* The Object is put as both the entry key and value.
* Will convert the Object to the target Map's parameterized types K,V if necessary.
*
* @author Keith Donald
* @since 3.0
*/
final class ObjectToMapConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public ObjectToMapConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object.class, Map.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType, targetType.getMapKeyTypeDescriptor())
&& this.conversionService.canConvert(sourceType, targetType.getMapValueTypeDescriptor());
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return this.conversionService.convertNullSource(sourceType, targetType);
}
Map target = CollectionFactory.createMap(targetType.getType(), 1);
TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor();
TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor();
boolean keysCompatible = false;
if (sourceType != TypeDescriptor.NULL && sourceType.isAssignableTo(targetKeyType)) {
keysCompatible = true;
}
boolean valuesCompatible = false;
if (sourceType != TypeDescriptor.NULL && sourceType.isAssignableTo(targetValueType)) {
valuesCompatible = true;
}
MapEntryConverter converter = new MapEntryConverter(sourceType, sourceType, targetKeyType, targetValueType,
keysCompatible, valuesCompatible, this.conversionService);
Object key = converter.convertKey(source);
Object value = converter.convertValue(source);
target.put(key, value);
return target;
}
}

View File

@ -38,15 +38,13 @@ import org.springframework.util.ReflectionUtils;
* Else throws a ConversionFailedException.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
final class ObjectToObjectGenericConverter implements ConditionalGenericConverter {
final class ObjectToObjectConverter implements ConditionalGenericConverter {
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> sourceClass = sourceType.getObjectType();
Class<?> targetClass = targetType.getObjectType();
return getValueOfMethodOn(targetClass, sourceClass) != null ||
getConstructor(targetClass, sourceClass) != null;
return hasValueOfMethodOrConstructor(targetType.getObjectType(), sourceType.getObjectType());
}
public Set<ConvertiblePair> getConvertibleTypes() {
@ -91,11 +89,16 @@ final class ObjectToObjectGenericConverter implements ConditionalGenericConverte
return target;
}
private Method getValueOfMethodOn(Class<?> targetClass, Class<?> argType) {
return ClassUtils.getStaticMethod(targetClass, "valueOf", argType);
public static boolean hasValueOfMethodOrConstructor(Class<?> targetClass, Class<?> sourceClass) {
return (getValueOfMethodOn(targetClass, sourceClass) != null || getConstructor(targetClass, sourceClass) != null);
}
private static Method getValueOfMethodOn(Class<?> targetClass, Class<?> sourceClass) {
return ClassUtils.getStaticMethod(targetClass, "valueOf", sourceClass);
}
private Constructor<?> getConstructor(Class<?> targetClass, Class<?> sourceClass) {
private static Constructor<?> getConstructor(Class<?> targetClass, Class<?> sourceClass) {
return ClassUtils.getConstructorIfAvailable(targetClass, sourceClass);
}

View File

@ -16,20 +16,41 @@
package org.springframework.core.convert.support;
import org.springframework.core.convert.converter.Converter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
/**
* Simply calls {@link Object#toString()} to convert any object to a string.
* Used by the {@link DefaultConversionService} as a fallback if there are
* no other explicit to string converters registered.
* Simply calls {@link Object#toString()} to convert any supported Object to a String.
* Supports Number, Boolean, Character, CharSequence, StringWriter, any enum,
* and any class with a String constructor or <code>valueOf(String)</code> method.
*
* <p>Used by the default ConversionService as a fallback if there are no other explicit
* to-String converters registered.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
final class ObjectToStringConverter implements Converter<Object, String> {
final class ObjectToStringConverter implements ConditionalGenericConverter {
public String convert(Object source) {
return source.toString();
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class sourceClass = sourceType.getObjectType();
return Number.class.isAssignableFrom(sourceClass) || Boolean.class.equals(sourceClass) ||
Character.class.equals(sourceClass) || CharSequence.class.isAssignableFrom(sourceClass) ||
StringWriter.class.isAssignableFrom(sourceClass) || sourceClass.isEnum() ||
ObjectToObjectConverter.hasValueOfMethodOrConstructor(sourceClass, String.class);
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object.class, String.class));
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return (source != null ? source.toString() : null);
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
@ -35,16 +33,16 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
* @since 3.0
* @see Properties#store(java.io.OutputStream, String)
*/
final class MapToStringConverter implements ConditionalGenericConverter {
final class PropertiesToStringConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public MapToStringConverter(GenericConversionService conversionService) {
public PropertiesToStringConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Map.class, String.class));
return Collections.singleton(new ConvertiblePair(Properties.class, String.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -59,11 +57,12 @@ final class MapToStringConverter implements ConditionalGenericConverter {
Map<?, ?> sourceMap = (Map<?, ?>) source;
if (sourceMap.size() == 0) {
return "";
} else {
}
else {
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap);
TypeDescriptor[] sourceEntryTypes = ConversionUtils.getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1];
}
@ -82,7 +81,8 @@ final class MapToStringConverter implements ConditionalGenericConverter {
props.setProperty((String) mapEntry.getKey(), (String) mapEntry.getValue());
}
return store(props);
} else {
}
else {
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetType,
targetType, keysCompatible, valuesCompatible, this.conversionService);
for (Object entry : sourceMap.entrySet()) {
@ -101,9 +101,10 @@ final class MapToStringConverter implements ConditionalGenericConverter {
ByteArrayOutputStream os = new ByteArrayOutputStream();
props.store(os, null);
return os.toString("ISO-8859-1");
} catch (IOException e) {
}
catch (IOException ex) {
// Should never happen.
throw new IllegalArgumentException("Failed to store [" + props + "] into String", e);
throw new IllegalArgumentException("Failed to store [" + props + "] into String", ex);
}
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Set;
@ -67,7 +65,7 @@ final class StringToArrayConverter implements ConditionalGenericConverter {
throw new ConverterNotFoundException(sourceType, targetElementType);
}
for (int i = 0; i < fields.length; i++) {
Array.set(target, i, invokeConverter(converter, fields[i], sourceType, targetElementType));
Array.set(target, i, ConversionUtils.invokeConverter(converter, fields[i], sourceType, targetElementType));
}
return target;
}

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
@ -61,8 +59,8 @@ final class StringToCollectionConverter implements ConditionalGenericConverter {
Collection target = CollectionFactory.createCollection(targetType.getType(), fields.length);
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
for (int i = 0; i < fields.length; i++) {
target.add(fields[i]);
for (String field : fields) {
target.add(field);
}
}
else {
@ -70,10 +68,10 @@ final class StringToCollectionConverter implements ConditionalGenericConverter {
if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetElementType);
}
for (int i = 0; i < fields.length; i++) {
String sourceElement = fields[i];
Object targetElement = invokeConverter(converter, sourceElement, sourceType, targetElementType);
target.add(targetElement);
for (String sourceElement : fields) {
Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceType, targetElementType);
target.add(targetElement);
}
}
return target;

View File

@ -18,7 +18,6 @@ package org.springframework.core.convert.support;
import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@ -32,16 +31,16 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
* @since 3.0
* @see Properties#load(java.io.InputStream)
*/
final class StringToMapConverter implements ConditionalGenericConverter {
final class StringToPropertiesConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService;
public StringToMapConverter(GenericConversionService conversionService) {
public StringToPropertiesConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, Map.class));
return Collections.singleton(new ConvertiblePair(String.class, Properties.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -63,9 +62,10 @@ final class StringToMapConverter implements ConditionalGenericConverter {
// Must use the ISO-8859-1 encoding because Properties.load(stream) expects it.
props.load(new ByteArrayInputStream(string.getBytes("ISO-8859-1")));
return props;
} catch (Exception e) {
}
catch (Exception ex) {
// Should never happen.
throw new IllegalArgumentException("Failed to parse [" + string + "] into Properties", e);
throw new IllegalArgumentException("Failed to parse [" + string + "] into Properties", ex);
}
}

View File

@ -16,10 +16,6 @@
package org.springframework.core.convert.support;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.AbstractList;
@ -38,14 +34,21 @@ import java.util.Properties;
import java.util.Set;
import junit.framework.Assert;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
/**
* @author Keith Donald
* @author Juergen Hoeller
*/
public class DefaultConversionTests {
private ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
@ -336,22 +339,6 @@ public class DefaultConversionTests {
conversionService.convert(new String[] { "1", "2", "3" }, AbstractList.class);
}
@Test
public void convertArrayToMap() {
Map result = conversionService.convert(new String[] { "foo=bar", "bar=baz", "baz=boop" }, Map.class);
assertEquals("bar", result.get("foo"));
assertEquals("baz", result.get("bar"));
assertEquals("boop", result.get("baz"));
}
@Test
public void convertArrayToMapWithElementConversion() throws Exception {
Map result = (Map) conversionService.convert(new String[] { "1=BAR", "2=BAZ" }, TypeDescriptor
.valueOf(String[].class), new TypeDescriptor(getClass().getField("genericMap")));
assertEquals(FooEnum.BAR, result.get(1));
assertEquals(FooEnum.BAZ, result.get(2));
}
public static enum FooEnum {
BAR, BAZ
}
@ -460,29 +447,6 @@ public class DefaultConversionTests {
assertEquals(new Integer(3), bar.get(2));
}
@Test
public void convertCollectionToMap() {
List<String> list = new ArrayList<String>();
list.add("foo=bar");
list.add("bar=baz");
list.add("baz=boop");
Map result = conversionService.convert(list, Map.class);
assertEquals("bar", result.get("foo"));
assertEquals("baz", result.get("bar"));
assertEquals("boop", result.get("baz"));
}
@Test
public void convertCollectionToMapWithElementConversion() throws Exception {
List<String> list = new ArrayList<String>();
list.add("1=BAR");
list.add("2=BAZ");
Map result = (Map) conversionService.convert(list, TypeDescriptor.valueOf(List.class), new TypeDescriptor(
getClass().getField("genericMap")));
assertEquals(FooEnum.BAR, result.get(1));
assertEquals(FooEnum.BAZ, result.get(2));
}
@Test
public void convertCollectionToString() {
List<String> list = Arrays.asList(new String[] { "foo", "bar" });
@ -526,68 +490,25 @@ public class DefaultConversionTests {
}
@Test
public void convertMapToStringArray() throws Exception {
Map<String, String> foo = new LinkedHashMap<String, String>();
foo.put("1", "BAR");
foo.put("2", "BAZ");
String[] result = conversionService.convert(foo, String[].class);
assertEquals("1=BAR", result[0]);
assertEquals("2=BAZ", result[1]);
}
@Test
public void convertMapToStringArrayWithElementConversion() throws Exception {
Map<Integer, FooEnum> foo = new LinkedHashMap<Integer, FooEnum>();
foo.put(1, FooEnum.BAR);
foo.put(2, FooEnum.BAZ);
String[] result = (String[]) conversionService.convert(foo, new TypeDescriptor(getClass()
.getField("genericMap")), TypeDescriptor.valueOf(String[].class));
assertEquals("1=BAR", result[0]);
assertEquals("2=BAZ", result[1]);
}
@Test
public void convertMapToString() {
Map<String, String> foo = new LinkedHashMap<String, String>();
foo.put("1", "BAR");
foo.put("2", "BAZ");
public void convertPropertiesToString() {
Properties foo = new Properties();
foo.setProperty("1", "BAR");
foo.setProperty("2", "BAZ");
String result = conversionService.convert(foo, String.class);
assertTrue(result.contains("1=BAR"));
assertTrue(result.contains("2=BAZ"));
}
@Test
public void convertMapToStringWithConversion() throws Exception {
Map<Integer, FooEnum> foo = new LinkedHashMap<Integer, FooEnum>();
public void convertPropertiesToStringWithConversion() throws Exception {
Properties foo = new Properties();
foo.put(1, FooEnum.BAR);
foo.put(2, FooEnum.BAZ);
String result = (String) conversionService.convert(foo, new TypeDescriptor(getClass().getField("genericMap")),
TypeDescriptor.valueOf(String.class));
String result = conversionService.convert(foo, String.class);
assertTrue(result.contains("1=BAR"));
assertTrue(result.contains("2=BAZ"));
}
@Test
public void convertMapToObject() {
Map<Long, Long> foo = new LinkedHashMap<Long, Long>();
foo.put(1L, 1L);
foo.put(2L, 2L);
Long result = conversionService.convert(foo, Long.class);
assertEquals(new Long(1), result);
}
public Map<Long, Long> genericMap2 = new HashMap<Long, Long>();
@Test
public void convertMapToObjectWithConversion() throws Exception {
Map<Long, Long> foo = new LinkedHashMap<Long, Long>();
foo.put(1L, 1L);
foo.put(2L, 2L);
Integer result = (Integer) conversionService.convert(foo,
new TypeDescriptor(getClass().getField("genericMap2")), TypeDescriptor.valueOf(Integer.class));
assertEquals(new Integer(1), result);
}
@Test
public void convertStringToArray() {
String[] result = conversionService.convert("1,2,3", String[].class);
@ -624,6 +545,14 @@ public class DefaultConversionTests {
assertEquals("", result.getProperty("d"));
}
@Test
public void convertStringToPropertiesWithSpaces() {
Properties result = conversionService.convert(" foo=bar\n bar=baz\n baz=boop", Properties.class);
assertEquals("bar", result.get("foo"));
assertEquals("baz", result.get("bar"));
assertEquals("boop", result.get("baz"));
}
@Test
public void convertEmptyStringToArray() {
String[] result = conversionService.convert("", String[].class);
@ -684,35 +613,6 @@ public class DefaultConversionTests {
assertEquals(new Integer(3), result.get(0));
}
@Test
public void convertStringToMap() {
Map result = conversionService.convert(" foo=bar\n bar=baz\n baz=boop", Map.class);
assertEquals("bar", result.get("foo"));
assertEquals("baz", result.get("bar"));
assertEquals("boop", result.get("baz"));
}
@Test
public void convertStringToMapWithElementConversion() throws Exception {
Map result = (Map) conversionService.convert("1=BAR\n 2=BAZ", TypeDescriptor.valueOf(String.class),
new TypeDescriptor(getClass().getField("genericMap")));
assertEquals(FooEnum.BAR, result.get(1));
assertEquals(FooEnum.BAZ, result.get(2));
}
@Test
public void convertObjectToMap() {
Map result = conversionService.convert(new Integer(3), Map.class);
assertEquals(new Integer(3), result.get(new Integer(3)));
}
@Test
public void convertObjectToMapWithConversion() throws Exception {
Map result = (Map) conversionService.convert(1L, TypeDescriptor.valueOf(Integer.class), new TypeDescriptor(
getClass().getField("genericMap2")));
assertEquals(new Long(1), result.get(1L));
}
@Test
@SuppressWarnings("unchecked")
public void testUnmodifiableListConversion() {

View File

@ -16,19 +16,14 @@
package org.springframework.core.convert.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
@ -88,7 +83,7 @@ public class GenericConversionServiceTests {
}
public void convertNullTargetClass() {
assertNull(conversionService.convert("3", (Class<?>) null));
assertNull(conversionService.convert("3", null));
}
@Test
@ -144,7 +139,7 @@ public class GenericConversionServiceTests {
@Test
public void genericConverterDelegatingBackToConversionServiceConverterNotFound() {
conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService));
conversionService.addConverter(new ObjectToArrayConverter(conversionService));
assertFalse(conversionService.canConvert(String.class, Integer[].class));
}