updated formatter conversion service adapter to work with type descriptor

This commit is contained in:
Keith Donald 2009-09-17 19:48:55 +00:00
parent 39c1ab923f
commit 31441627de
4 changed files with 26 additions and 32 deletions

View File

@ -21,9 +21,9 @@ import java.text.ParseException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.convert.support.GenericConverter;
import org.springframework.ui.format.Formatter;
import org.springframework.ui.format.FormatterRegistry;
import org.springframework.util.Assert;
@ -40,7 +40,6 @@ public class FormattingConversionServiceAdapter extends GenericConversionService
private final FormatterRegistry formatterRegistry;
/**
* Create a new FormattingConversionServiceAdapter for the given FormatterRegistry.
* @param formatterRegistry the FormatterRegistry to wrap
@ -50,28 +49,26 @@ public class FormattingConversionServiceAdapter extends GenericConversionService
this.formatterRegistry = formatterRegistry;
if (formatterRegistry instanceof GenericFormatterRegistry) {
setParent(((GenericFormatterRegistry) formatterRegistry).getConversionService());
}
else {
} else {
setParent(new DefaultConversionService());
}
}
@Override
protected Converter findConverter(Class<?> sourceType, TypeDescriptor targetType) {
protected GenericConverter getConverter(Class sourceType, TypeDescriptor targetType) {
if (String.class.equals(sourceType)) {
Formatter formatter = this.formatterRegistry.getFormatter(targetType);
if (formatter != null) {
return new FormattingConverter(formatter);
}
}
return super.findConverter(sourceType, targetType);
return super.getConverter(sourceType, targetType);
}
/**
* Adapter that exposes the Converter interface on top of a given Formatter.
*/
private static class FormattingConverter implements Converter<String, Object> {
private static class FormattingConverter implements GenericConverter {
private final Formatter formatter;
@ -79,11 +76,10 @@ public class FormattingConversionServiceAdapter extends GenericConversionService
this.formatter = formatter;
}
public Object convert(String source) {
public Object convert(Object source, TypeDescriptor targetType) {
try {
return this.formatter.parse(source, LocaleContextHolder.getLocale());
}
catch (ParseException ex) {
return this.formatter.parse((String) source, LocaleContextHolder.getLocale());
} catch (ParseException ex) {
throw new IllegalArgumentException("Could not convert formatted value '" + source + "'", ex);
}
}

View File

@ -31,23 +31,24 @@ import org.springframework.core.convert.TypeDescriptor;
class CollectionToCollectionGenericConverter implements GenericConverter {
private GenericConversionService conversionService;
public CollectionToCollectionGenericConverter(GenericConversionService conversionService) {
this.conversionService = conversionService;
}
public Object convert(Object source, TypeDescriptor targetType) {
Collection sourceCollection = (Collection) source;
Object firstNotNullElement = getFirstNotNullElement(sourceCollection);
if (firstNotNullElement == null) {
return compatibleCollectionWithoutElementConversion(sourceCollection, targetType);
}
Class targetElementType = targetType.getElementType();
Class targetElementType = targetType.getElementType();
if (targetElementType == null || targetElementType.isAssignableFrom(firstNotNullElement.getClass())) {
return compatibleCollectionWithoutElementConversion(sourceCollection, targetType);
}
Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
GenericConverter elementConverter = conversionService.getConverter(firstNotNullElement.getClass(), targetElementType);
GenericConverter elementConverter = conversionService.getConverter(firstNotNullElement.getClass(),
TypeDescriptor.valueOf(targetElementType));
for (Object element : sourceCollection) {
targetCollection.add(elementConverter.convert(element, TypeDescriptor.valueOf(targetElementType)));
}
@ -65,7 +66,7 @@ class CollectionToCollectionGenericConverter implements GenericConverter {
return target;
}
}
private Object getFirstNotNullElement(Collection collection) {
for (Object element : collection) {
if (element != null) {
@ -74,5 +75,5 @@ class CollectionToCollectionGenericConverter implements GenericConverter {
}
return null;
}
}

View File

@ -54,10 +54,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
private ConversionService parent;
/**
* An indexed map of Converters. Each Map.Entry key is a source class (S) that can be converted from.
* Each Map.Entry value is a Map that defines the targetType-to-Converter mappings for that source.
*/
private final Map<Class, Map<Class, GenericConverter>> sourceTypeConverters = new HashMap<Class, Map<Class, GenericConverter>>();
public GenericConversionService() {
@ -143,7 +139,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
}
Class sourceClass = ClassUtils.resolvePrimitiveIfNecessary(sourceType);
Class targetClass = targetType.getObjectType();
return getConverter(sourceClass, targetType.getObjectType()) != null || this.parent != null
return getConverter(sourceClass, targetType) != null || this.parent != null
&& this.parent.canConvert(sourceClass, targetClass);
}
@ -161,7 +157,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
return null;
}
Class sourceType = ClassUtils.resolvePrimitiveIfNecessary(source.getClass());
GenericConverter converter = getConverter(sourceType, targetType.getObjectType());
GenericConverter converter = getConverter(sourceType, targetType);
if (converter != null) {
try {
return converter.convert(source, targetType);
@ -181,7 +177,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
// subclassing hooks
protected GenericConverter getConverter(Class<?> sourceType, Class<?> targetType) {
protected GenericConverter getConverter(Class sourceType, TypeDescriptor targetType) {
if (sourceType.isInterface()) {
LinkedList<Class> classQueue = new LinkedList<Class>();
classQueue.addFirst(sourceType);
@ -223,7 +219,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
// internal helpers
private void addGenericConverter(Class<?> sourceType, Class<?> targetType, GenericConverter converter) {
private void addGenericConverter(Class sourceType, Class targetType, GenericConverter converter) {
getSourceMap(sourceType).put(targetType, converter);
}
@ -287,7 +283,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
return sourceMap;
}
private Map<Class, GenericConverter> getConvertersForSource(Class<?> sourceType) {
private Map<Class, GenericConverter> getConvertersForSource(Class sourceType) {
Map<Class, GenericConverter> converters = this.sourceTypeConverters.get(sourceType);
if (converters == null) {
converters = Collections.emptyMap();
@ -295,10 +291,11 @@ public class GenericConversionService implements ConversionService, ConverterReg
return converters;
}
private GenericConverter getConverter(Map<Class, GenericConverter> converters, Class<?> targetType) {
if (targetType.isInterface()) {
private GenericConverter getConverter(Map<Class, GenericConverter> converters, TypeDescriptor targetType) {
Class targetClass = targetType.getObjectType();
if (targetClass.isInterface()) {
LinkedList<Class> classQueue = new LinkedList<Class>();
classQueue.addFirst(targetType);
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
Class currentClass = classQueue.removeLast();
GenericConverter converter = converters.get(currentClass);
@ -313,7 +310,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
return converters.get(Object.class);
} else {
LinkedList<Class> classQueue = new LinkedList<Class>();
classQueue.addFirst(targetType);
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
Class currentClass = classQueue.removeLast();
GenericConverter converter = converters.get(currentClass);

View File

@ -2,7 +2,7 @@ package org.springframework.core.convert.support;
import org.springframework.core.convert.TypeDescriptor;
interface GenericConverter {
public interface GenericConverter {
Object convert(Object source, TypeDescriptor type);