revised default converters; renamed ConverterRegistry's addGenericConverter to addConverter

This commit is contained in:
Juergen Hoeller 2009-12-14 21:14:26 +00:00
parent c2e1f113f5
commit 6622c71935
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 class FormattingConversionService extends GenericConversionService implements FormatterRegistry {
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) { public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) {
addGenericConverter(new PrinterConverter(fieldType, formatter, this)); addConverter(new PrinterConverter(fieldType, formatter, this));
addGenericConverter(new ParserConverter(fieldType, formatter, this)); addConverter(new ParserConverter(fieldType, formatter, this));
} }
public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) { public void addFormatterForFieldType(Class<?> fieldType, Printer<?> printer, Parser<?> parser) {
addGenericConverter(new PrinterConverter(fieldType, printer, this)); addConverter(new PrinterConverter(fieldType, printer, this));
addGenericConverter(new ParserConverter(fieldType, parser, this)); addConverter(new ParserConverter(fieldType, parser, this));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -67,7 +67,7 @@ public class FormattingConversionService extends GenericConversionService implem
Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes(); Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes();
for (final Class<?> fieldType : fieldTypes) { for (final Class<?> fieldType : fieldTypes) {
addGenericConverter(new ConditionalGenericConverter() { addConverter(new ConditionalGenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() { public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(fieldType, String.class)); return Collections.singleton(new ConvertiblePair(fieldType, String.class));
} }
@ -83,7 +83,7 @@ public class FormattingConversionService extends GenericConversionService implem
String.class.getName() + ": " + annotationFormatterFactory; String.class.getName() + ": " + annotationFormatterFactory;
} }
}); });
addGenericConverter(new ConditionalGenericConverter() { addConverter(new ConditionalGenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() { public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, fieldType)); return Collections.singleton(new ConvertiblePair(String.class, fieldType));
} }

View File

@ -381,7 +381,8 @@ public class TypeDescriptor {
if (collectionType != null) { if (collectionType != null) {
stringValue.append("<").append(collectionType.getName()).append(">"); stringValue.append("<").append(collectionType.getName()).append(">");
} }
} else if (isMap()) { }
else if (isMap()) {
Class<?> keyType = getMapKeyType(); Class<?> keyType = getMapKeyType();
Class<?> valType = getMapValueType(); Class<?> valType = getMapValueType();
if (keyType != null && valType != null) { 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. * For registering converters with a type conversion system.
* *
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
public interface ConverterRegistry { 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); void addConverter(Converter<?, ?> converter);
@ -34,11 +40,6 @@ public interface ConverterRegistry {
*/ */
void addConverterFactory(ConverterFactory<?, ?> converterFactory); void addConverterFactory(ConverterFactory<?, ?> converterFactory);
/**
* Add a generic converter to this registry.
*/
void addGenericConverter(GenericConverter converter);
/** /**
* Remove any converters from sourceType to targetType. * Remove any converters from sourceType to targetType.
* @param sourceType the source type * @param sourceType the source type

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -31,9 +29,11 @@ import org.springframework.core.convert.converter.GenericConverter;
/** /**
* Converts an Array to a Collection. * 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. * 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 * @author Keith Donald
* @since 3.0 * @since 3.0
@ -75,7 +75,8 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
} }
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, 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); 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; 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.lang.reflect.Array;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -31,11 +28,13 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
/** /**
* Converts a Collection to an Array. * 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. * <p>First, creates a new array of the requested targetType with a length equal to the
* Will perform an element conversion from the collection's parameterized type to the array's component type if necessary. * 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 * @author Keith Donald
* @since 3.0 * @since 3.0
*/ */
@ -62,7 +61,7 @@ final class CollectionToArrayConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source; Collection<?> sourceCollection = (Collection<?>) source;
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) { if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection); sourceElementType = ConversionUtils.getElementType(sourceCollection);
} }
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
Object array = Array.newInstance(targetElementType.getType(), sourceCollection.size()); 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++) { for (Iterator<?> it = sourceCollection.iterator(); it.hasNext(); i++) {
Object sourceElement = it.next(); Object sourceElement = it.next();
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetElementType); Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceElementType, targetElementType);
Array.set(array, i, targetElement); 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.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
import static org.springframework.core.convert.support.ConversionUtils.*;
/** /**
* Converts from a Collection to another Collection. * 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. * <p>First, creates a new Collection of the requested targetType with a size equal to the
* Will perform an element conversion from the source collection's parameterized type to the target collection's parameterized type if necessary. * 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 * @author Keith Donald
* @since 3.0 * @since 3.0
@ -60,14 +61,15 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert
Collection<?> sourceCollection = (Collection<?>) source; Collection<?> sourceCollection = (Collection<?>) source;
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) { if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection); sourceElementType = ConversionUtils.getElementType(sourceCollection);
} }
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL || targetElementType == TypeDescriptor.NULL if (sourceElementType == TypeDescriptor.NULL || targetElementType == TypeDescriptor.NULL
|| sourceElementType.isAssignableTo(targetElementType)) { || sourceElementType.isAssignableTo(targetElementType)) {
if (sourceType.isAssignableTo(targetType)) { if (sourceType.isAssignableTo(targetType)) {
return sourceCollection; return sourceCollection;
} else { }
else {
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
target.addAll(sourceCollection); target.addAll(sourceCollection);
return target; return target;
@ -79,7 +81,7 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert
throw new ConverterNotFoundException(sourceElementType, targetElementType); throw new ConverterNotFoundException(sourceElementType, targetElementType);
} }
for (Object element : sourceCollection) { for (Object element : sourceCollection) {
target.add(invokeConverter(converter, element, sourceElementType, targetElementType)); target.add(ConversionUtils.invokeConverter(converter, element, sourceElementType, targetElementType));
} }
return target; 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; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -56,7 +54,8 @@ final class CollectionToObjectConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source; Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.size() == 0) { if (sourceCollection.size() == 0) {
return null; return null;
} else { }
else {
Object firstElement = sourceCollection.iterator().next(); Object firstElement = sourceCollection.iterator().next();
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL && firstElement != null) { if (sourceElementType == TypeDescriptor.NULL && firstElement != null) {
@ -64,12 +63,13 @@ final class CollectionToObjectConverter implements ConditionalGenericConverter {
} }
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) { if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
return firstElement; return firstElement;
} else { }
else {
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType); GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
if (converter == null) { if (converter == null) {
throw new ConverterNotFoundException(sourceElementType, targetType); 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; 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.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -59,10 +56,11 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
Collection<?> sourceCollection = (Collection<?>) source; Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.size() == 0) { if (sourceCollection.size() == 0) {
return ""; return "";
} else { }
else {
TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor();
if (sourceElementType == TypeDescriptor.NULL) { if (sourceElementType == TypeDescriptor.NULL) {
sourceElementType = getElementType(sourceCollection); sourceElementType = ConversionUtils.getElementType(sourceCollection);
} }
if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) { if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetType)) {
StringBuilder string = new StringBuilder(); StringBuilder string = new StringBuilder();
@ -75,7 +73,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
i++; i++;
} }
return string.toString(); return string.toString();
} else { }
else {
GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType); GenericConverter converter = this.conversionService.getConverter(sourceElementType, targetType);
if (converter == null) { if (converter == null) {
throw new ConverterNotFoundException(sourceElementType, targetType); throw new ConverterNotFoundException(sourceElementType, targetType);
@ -86,7 +85,8 @@ final class CollectionToStringConverter implements ConditionalGenericConverter {
if (i > 0) { if (i > 0) {
string.append(DELIMITER); string.append(DELIMITER);
} }
Object targetElement = invokeConverter(converter, sourceElement, sourceElementType, targetType); Object targetElement = ConversionUtils.invokeConverter(
converter, sourceElement, sourceElementType, targetType);
string.append(targetElement); string.append(targetElement);
i++; 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. * Populate the given ConversionService instance with all applicable default converters.
*/ */
public static void addDefaultConverters(GenericConversionService conversionService) { public static void addDefaultConverters(GenericConversionService conversionService) {
conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService)); conversionService.addConverter(new ArrayToArrayConverter(conversionService));
conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); conversionService.addConverter(new ArrayToCollectionConverter(conversionService));
conversionService.addGenericConverter(new ArrayToMapConverter(conversionService)); conversionService.addConverter(new ArrayToStringConverter(conversionService));
conversionService.addGenericConverter(new ArrayToStringConverter(conversionService)); conversionService.addConverter(new ArrayToObjectConverter(conversionService));
conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); conversionService.addConverter(new CollectionToCollectionConverter(conversionService));
conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverter(new CollectionToArrayConverter(conversionService));
conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService)); conversionService.addConverter(new CollectionToStringConverter(conversionService));
conversionService.addGenericConverter(new CollectionToMapConverter(conversionService)); conversionService.addConverter(new CollectionToObjectConverter(conversionService));
conversionService.addGenericConverter(new CollectionToStringConverter(conversionService)); conversionService.addConverter(new MapToMapConverter(conversionService));
conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); conversionService.addConverter(new PropertiesToStringConverter(conversionService));
conversionService.addGenericConverter(new MapToMapConverter(conversionService)); conversionService.addConverter(new StringToArrayConverter(conversionService));
conversionService.addGenericConverter(new MapToArrayConverter(conversionService)); conversionService.addConverter(new StringToCollectionConverter(conversionService));
conversionService.addGenericConverter(new MapToCollectionConverter(conversionService)); conversionService.addConverter(new StringToPropertiesConverter(conversionService));
conversionService.addGenericConverter(new MapToStringConverter(conversionService)); conversionService.addConverter(new ObjectToArrayConverter(conversionService));
conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); conversionService.addConverter(new ObjectToCollectionConverter(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.addConverterFactory(new CharacterToNumberFactory()); conversionService.addConverterFactory(new CharacterToNumberFactory());
conversionService.addConverter(new NumberToCharacterConverter()); conversionService.addConverter(new NumberToCharacterConverter());
conversionService.addConverterFactory(new NumberToNumberConverterFactory()); conversionService.addConverterFactory(new NumberToNumberConverterFactory());
@ -76,8 +70,8 @@ public abstract class ConversionServiceFactory {
conversionService.addConverter(new StringToLocaleConverter()); conversionService.addConverter(new StringToLocaleConverter());
conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToNumberConverterFactory());
conversionService.addConverter(new ObjectToStringConverter()); conversionService.addConverter(new ObjectToStringConverter());
conversionService.addGenericConverter(new ObjectToObjectGenericConverter()); conversionService.addConverter(new ObjectToObjectConverter());
conversionService.addGenericConverter(new IdToEntityConverter(conversionService)); conversionService.addConverter(new IdToEntityConverter(conversionService));
} }
/** /**
@ -89,15 +83,15 @@ public abstract class ConversionServiceFactory {
public static void registerConverters(Set<Object> converters, ConverterRegistry registry) { public static void registerConverters(Set<Object> converters, ConverterRegistry registry) {
if (converters != null) { if (converters != null) {
for (Object converter : converters) { 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); registry.addConverter((Converter<?, ?>) converter);
} }
else if (converter instanceof ConverterFactory<?, ?>) { else if (converter instanceof ConverterFactory<?, ?>) {
registry.addConverterFactory((ConverterFactory<?, ?>) converter); registry.addConverterFactory((ConverterFactory<?, ?>) converter);
} }
else if (converter instanceof GenericConverter) {
registry.addGenericConverter((GenericConverter) converter);
}
else { else {
throw new IllegalArgumentException("Each converter object must implement one of the " + throw new IllegalArgumentException("Each converter object must implement one of the " +
"Converter, ConverterFactory, or GenericConverter interfaces"); "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.ConverterFactory;
import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
import static org.springframework.core.convert.support.ConversionUtils.*;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -71,13 +70,20 @@ public class GenericConversionService implements ConversionService, ConverterReg
// implementing ConverterRegistry // 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) { public void addConverter(Converter<?, ?> converter) {
GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class); GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class);
if (typeInfo == null) { if (typeInfo == null) {
throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> which " + throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetType <T> which " +
"your Converter<S, T> converts between; declare these generic types."); "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) { 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 " + throw new IllegalArgumentException("Unable to the determine sourceType <S> and targetRangeType R which " +
"your ConverterFactory<S, R> converts between; declare these generic types."); "your ConverterFactory<S, R> converts between; declare these generic types.");
} }
addGenericConverter(new ConverterFactoryAdapter(typeInfo, converterFactory)); addConverter(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);
}
} }
public void removeConvertible(Class<?> sourceType, Class<?> targetType) { public void removeConvertible(Class<?> sourceType, Class<?> targetType) {
@ -133,7 +132,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (converter == null) { if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetType); throw new ConverterNotFoundException(sourceType, targetType);
} }
return invokeConverter(converter, source, sourceType, targetType); return ConversionUtils.invokeConverter(converter, source, sourceType, targetType);
} }
public String toString() { public String toString() {
@ -368,7 +367,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
return (matchable != null ? matchable.matchConverter(sourceFieldType, targetFieldType) : null); return (matchable != null ? matchable.matchConverter(sourceFieldType, targetFieldType) : null);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private final class ConverterAdapter implements GenericConverter { private final class ConverterAdapter implements GenericConverter {

View File

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

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support; 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.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
@ -45,6 +43,7 @@ class MapEntryConverter {
public MapEntryConverter(TypeDescriptor sourceKeyType, TypeDescriptor sourceValueType, public MapEntryConverter(TypeDescriptor sourceKeyType, TypeDescriptor sourceValueType,
TypeDescriptor targetKeyType, TypeDescriptor targetValueType, boolean keysCompatible, TypeDescriptor targetKeyType, TypeDescriptor targetValueType, boolean keysCompatible,
boolean valuesCompatible, GenericConversionService conversionService) { boolean valuesCompatible, GenericConversionService conversionService) {
if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL && !keysCompatible) { if (sourceKeyType != TypeDescriptor.NULL && targetKeyType != TypeDescriptor.NULL && !keysCompatible) {
this.keyConverter = conversionService.getConverter(sourceKeyType, targetKeyType); this.keyConverter = conversionService.getConverter(sourceKeyType, targetKeyType);
if (this.keyConverter == null) { if (this.keyConverter == null) {
@ -53,6 +52,7 @@ class MapEntryConverter {
this.sourceKeyType = sourceKeyType; this.sourceKeyType = sourceKeyType;
this.targetKeyType = targetKeyType; this.targetKeyType = targetKeyType;
} }
if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL && !valuesCompatible) { if (sourceValueType != TypeDescriptor.NULL && targetValueType != TypeDescriptor.NULL && !valuesCompatible) {
this.valueConverter = conversionService.getConverter(sourceValueType, targetValueType); this.valueConverter = conversionService.getConverter(sourceValueType, targetValueType);
if (this.valueConverter == null) { if (this.valueConverter == null) {
@ -65,16 +65,20 @@ class MapEntryConverter {
public Object convertKey(Object sourceKey) { public Object convertKey(Object sourceKey) {
if (sourceKey != null && this.keyConverter != null) { if (sourceKey != null && this.keyConverter != null) {
return invokeConverter(this.keyConverter, sourceKey, this.sourceKeyType, this.targetKeyType); return ConversionUtils.invokeConverter(
} else { this.keyConverter, sourceKey, this.sourceKeyType, this.targetKeyType);
}
else {
return sourceKey; return sourceKey;
} }
} }
public Object convertValue(Object sourceValue) { public Object convertValue(Object sourceValue) {
if (sourceValue != null && this.valueConverter != null) { if (sourceValue != null && this.valueConverter != null) {
return invokeConverter(this.valueConverter, sourceValue, this.sourceValueType, this.targetValueType); return ConversionUtils.invokeConverter(
} else { this.valueConverter, sourceValue, this.sourceValueType, this.targetValueType);
}
else {
return sourceValue; 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; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -28,9 +26,11 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
/** /**
* Converts a Map to another Map. * 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. * <p>First, creates a new Map of the requested targetType with a size equal to the
* Will perform a conversion from the source maps's parameterized K,V types to the target map's parameterized types K,V if necessary. * 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 * @author Keith Donald
* @since 3.0 * @since 3.0
@ -66,7 +66,7 @@ final class MapToMapConverter implements ConditionalGenericConverter {
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor(); TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor(); TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) { if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap); TypeDescriptor[] sourceEntryTypes = ConversionUtils.getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0]; sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1]; sourceValueType = sourceEntryTypes[1];
} }
@ -98,9 +98,10 @@ final class MapToMapConverter implements ConditionalGenericConverter {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<?, ?> compatibleMapWithoutEntryConversion(Map<?, ?> source, TypeDescriptor targetType) { private Map<?, ?> compatibleMapWithoutEntryConversion(Map<?, ?> source, TypeDescriptor targetType) {
if (targetType.getType().isAssignableFrom(source.getClass())) { if (targetType.getType().isInstance(source)) {
return source; return source;
} else { }
else {
Map target = CollectionFactory.createMap(targetType.getType(), source.size()); Map target = CollectionFactory.createMap(targetType.getType(), source.size());
target.putAll(source); target.putAll(source);
return target; 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; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -58,12 +56,13 @@ final class ObjectToArrayConverter implements ConditionalGenericConverter {
Object target = Array.newInstance(targetElementType.getType(), 1); Object target = Array.newInstance(targetElementType.getType(), 1);
if (sourceType.isAssignableTo(targetElementType)) { if (sourceType.isAssignableTo(targetElementType)) {
Array.set(target, 0, source); Array.set(target, 0, source);
} else { }
else {
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType); GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
if (converter == null) { if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetElementType); 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; return target;
} }

View File

@ -16,8 +16,6 @@
package org.springframework.core.convert.support; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -60,12 +58,13 @@ final class ObjectToCollectionConverter implements ConditionalGenericConverter {
TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); TypeDescriptor targetElementType = targetType.getElementTypeDescriptor();
if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) { if (targetElementType == TypeDescriptor.NULL || sourceType.isAssignableTo(targetElementType)) {
target.add(source); target.add(source);
} else { }
else {
GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType); GenericConverter converter = this.conversionService.getConverter(sourceType, targetElementType);
if (converter == null) { if (converter == null) {
throw new ConverterNotFoundException(sourceType, targetElementType); throw new ConverterNotFoundException(sourceType, targetElementType);
} }
target.add(invokeConverter(converter, source, sourceType, targetElementType)); target.add(ConversionUtils.invokeConverter(converter, source, sourceType, targetElementType));
} }
return target; 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. * Else throws a ConversionFailedException.
* *
* @author Keith Donald * @author Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
final class ObjectToObjectGenericConverter implements ConditionalGenericConverter { final class ObjectToObjectConverter implements ConditionalGenericConverter {
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
Class<?> sourceClass = sourceType.getObjectType(); return hasValueOfMethodOrConstructor(targetType.getObjectType(), sourceType.getObjectType());
Class<?> targetClass = targetType.getObjectType();
return getValueOfMethodOn(targetClass, sourceClass) != null ||
getConstructor(targetClass, sourceClass) != null;
} }
public Set<ConvertiblePair> getConvertibleTypes() { public Set<ConvertiblePair> getConvertibleTypes() {
@ -91,11 +89,16 @@ final class ObjectToObjectGenericConverter implements ConditionalGenericConverte
return target; 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); return ClassUtils.getConstructorIfAvailable(targetClass, sourceClass);
} }

View File

@ -16,20 +16,41 @@
package org.springframework.core.convert.support; 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. * Simply calls {@link Object#toString()} to convert any supported Object to a String.
* Used by the {@link DefaultConversionService} as a fallback if there are * Supports Number, Boolean, Character, CharSequence, StringWriter, any enum,
* no other explicit to string converters registered. * 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 Keith Donald
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
*/ */
final class ObjectToStringConverter implements Converter<Object, String> { final class ObjectToStringConverter implements ConditionalGenericConverter {
public String convert(Object source) { public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return source.toString(); 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; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.getMapEntryTypes;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -35,16 +33,16 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
* @since 3.0 * @since 3.0
* @see Properties#store(java.io.OutputStream, String) * @see Properties#store(java.io.OutputStream, String)
*/ */
final class MapToStringConverter implements ConditionalGenericConverter { final class PropertiesToStringConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService; private final GenericConversionService conversionService;
public MapToStringConverter(GenericConversionService conversionService) { public PropertiesToStringConverter(GenericConversionService conversionService) {
this.conversionService = conversionService; this.conversionService = conversionService;
} }
public Set<ConvertiblePair> getConvertibleTypes() { 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) { public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -59,11 +57,12 @@ final class MapToStringConverter implements ConditionalGenericConverter {
Map<?, ?> sourceMap = (Map<?, ?>) source; Map<?, ?> sourceMap = (Map<?, ?>) source;
if (sourceMap.size() == 0) { if (sourceMap.size() == 0) {
return ""; return "";
} else { }
else {
TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor(); TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor();
TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor(); TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor();
if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) { if (sourceKeyType == TypeDescriptor.NULL || sourceValueType == TypeDescriptor.NULL) {
TypeDescriptor[] sourceEntryTypes = getMapEntryTypes(sourceMap); TypeDescriptor[] sourceEntryTypes = ConversionUtils.getMapEntryTypes(sourceMap);
sourceKeyType = sourceEntryTypes[0]; sourceKeyType = sourceEntryTypes[0];
sourceValueType = sourceEntryTypes[1]; sourceValueType = sourceEntryTypes[1];
} }
@ -82,7 +81,8 @@ final class MapToStringConverter implements ConditionalGenericConverter {
props.setProperty((String) mapEntry.getKey(), (String) mapEntry.getValue()); props.setProperty((String) mapEntry.getKey(), (String) mapEntry.getValue());
} }
return store(props); return store(props);
} else { }
else {
MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetType, MapEntryConverter converter = new MapEntryConverter(sourceKeyType, sourceValueType, targetType,
targetType, keysCompatible, valuesCompatible, this.conversionService); targetType, keysCompatible, valuesCompatible, this.conversionService);
for (Object entry : sourceMap.entrySet()) { for (Object entry : sourceMap.entrySet()) {
@ -101,9 +101,10 @@ final class MapToStringConverter implements ConditionalGenericConverter {
ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream();
props.store(os, null); props.store(os, null);
return os.toString("ISO-8859-1"); return os.toString("ISO-8859-1");
} catch (IOException e) { }
catch (IOException ex) {
// Should never happen. // 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; package org.springframework.core.convert.support;
import static org.springframework.core.convert.support.ConversionUtils.invokeConverter;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -67,7 +65,7 @@ final class StringToArrayConverter implements ConditionalGenericConverter {
throw new ConverterNotFoundException(sourceType, targetElementType); throw new ConverterNotFoundException(sourceType, targetElementType);
} }
for (int i = 0; i < fields.length; i++) { 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; return target;
} }

View File

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

View File

@ -18,7 +18,6 @@ package org.springframework.core.convert.support;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -32,16 +31,16 @@ import org.springframework.core.convert.converter.ConditionalGenericConverter;
* @since 3.0 * @since 3.0
* @see Properties#load(java.io.InputStream) * @see Properties#load(java.io.InputStream)
*/ */
final class StringToMapConverter implements ConditionalGenericConverter { final class StringToPropertiesConverter implements ConditionalGenericConverter {
private final GenericConversionService conversionService; private final GenericConversionService conversionService;
public StringToMapConverter(GenericConversionService conversionService) { public StringToPropertiesConverter(GenericConversionService conversionService) {
this.conversionService = conversionService; this.conversionService = conversionService;
} }
public Set<ConvertiblePair> getConvertibleTypes() { 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) { 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. // Must use the ISO-8859-1 encoding because Properties.load(stream) expects it.
props.load(new ByteArrayInputStream(string.getBytes("ISO-8859-1"))); props.load(new ByteArrayInputStream(string.getBytes("ISO-8859-1")));
return props; return props;
} catch (Exception e) { }
catch (Exception ex) {
// Should never happen. // 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; 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.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.AbstractList; import java.util.AbstractList;
@ -38,14 +34,21 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import junit.framework.Assert; 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.junit.Test;
import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
/**
* @author Keith Donald
* @author Juergen Hoeller
*/
public class DefaultConversionTests { public class DefaultConversionTests {
private ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService(); private ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
@ -336,22 +339,6 @@ public class DefaultConversionTests {
conversionService.convert(new String[] { "1", "2", "3" }, AbstractList.class); 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 { public static enum FooEnum {
BAR, BAZ BAR, BAZ
} }
@ -460,29 +447,6 @@ public class DefaultConversionTests {
assertEquals(new Integer(3), bar.get(2)); 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 @Test
public void convertCollectionToString() { public void convertCollectionToString() {
List<String> list = Arrays.asList(new String[] { "foo", "bar" }); List<String> list = Arrays.asList(new String[] { "foo", "bar" });
@ -526,68 +490,25 @@ public class DefaultConversionTests {
} }
@Test @Test
public void convertMapToStringArray() throws Exception { public void convertPropertiesToString() {
Map<String, String> foo = new LinkedHashMap<String, String>(); Properties foo = new Properties();
foo.put("1", "BAR"); foo.setProperty("1", "BAR");
foo.put("2", "BAZ"); foo.setProperty("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");
String result = conversionService.convert(foo, String.class); String result = conversionService.convert(foo, String.class);
assertTrue(result.contains("1=BAR")); assertTrue(result.contains("1=BAR"));
assertTrue(result.contains("2=BAZ")); assertTrue(result.contains("2=BAZ"));
} }
@Test @Test
public void convertMapToStringWithConversion() throws Exception { public void convertPropertiesToStringWithConversion() throws Exception {
Map<Integer, FooEnum> foo = new LinkedHashMap<Integer, FooEnum>(); Properties foo = new Properties();
foo.put(1, FooEnum.BAR); foo.put(1, FooEnum.BAR);
foo.put(2, FooEnum.BAZ); foo.put(2, FooEnum.BAZ);
String result = (String) conversionService.convert(foo, new TypeDescriptor(getClass().getField("genericMap")), String result = conversionService.convert(foo, String.class);
TypeDescriptor.valueOf(String.class));
assertTrue(result.contains("1=BAR")); assertTrue(result.contains("1=BAR"));
assertTrue(result.contains("2=BAZ")); 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 @Test
public void convertStringToArray() { public void convertStringToArray() {
String[] result = conversionService.convert("1,2,3", String[].class); String[] result = conversionService.convert("1,2,3", String[].class);
@ -624,6 +545,14 @@ public class DefaultConversionTests {
assertEquals("", result.getProperty("d")); 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 @Test
public void convertEmptyStringToArray() { public void convertEmptyStringToArray() {
String[] result = conversionService.convert("", String[].class); String[] result = conversionService.convert("", String[].class);
@ -684,35 +613,6 @@ public class DefaultConversionTests {
assertEquals(new Integer(3), result.get(0)); 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 @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void testUnmodifiableListConversion() { public void testUnmodifiableListConversion() {

View File

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