From d85dc01e282d0e215cf6db0f8b45eb04eecf3eca Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 19 Nov 2009 09:10:51 +0000 Subject: [PATCH] moved generic converter to spi; added entity converter; removed various service impls in favor of service factory --- .../DefaultListableBeanFactoryTests.java | 30 ++-- .../support/FormattingConversionService.java | 69 ++++---- ...ormattingConversionServiceFactoryBean.java | 19 +-- .../ConversionServiceContextConfigTests.java | 2 + .../ConditionalGenericConverter.java | 3 +- .../ConverterMatcher.java | 3 +- .../convert/converter/ConverterRegistry.java | 10 +- .../GenericConverter.java | 12 +- .../support/ArrayToArrayConverter.java | 5 + .../support/ArrayToCollectionConverter.java | 5 + .../convert/support/ArrayToMapConverter.java | 7 + .../support/ArrayToObjectConverter.java | 5 + .../support/CollectionToArrayConverter.java | 5 + .../CollectionToCollectionConverter.java | 5 + .../support/CollectionToMapConverter.java | 6 +- .../support/CollectionToObjectConverter.java | 5 + .../support/ConversionServiceFactory.java | 63 ++++++++ .../core/convert/support/ConversionUtils.java | 1 + .../support/DefaultConversionService.java | 47 ------ .../core/convert/support/EntityConverter.java | 97 +++++++++++ .../support/GenericConversionService.java | 152 ++++-------------- .../convert/support/MapEntryConverter.java | 1 + .../convert/support/MapToArrayConverter.java | 6 + .../support/MapToCollectionConverter.java | 5 + .../convert/support/MapToMapConverter.java | 5 + .../convert/support/MapToObjectConverter.java | 5 + .../support/ObjectToArrayConverter.java | 5 + .../support/ObjectToCollectionConverter.java | 5 + .../convert/support/ObjectToMapConverter.java | 5 + .../ObjectToObjectGenericConverter.java | 5 + .../DefaultConversionServiceTests.java | 8 +- .../GenericConversionServiceTests.java | 142 ++++++---------- .../spel/support/StandardTypeConverter.java | 4 +- ...essionTestsUsingCoreConversionService.java | 5 +- .../spel/support/StandardComponentsTests.java | 4 +- .../web/servlet/config/MvcNamespaceTests.java | 1 - .../mvc-config-custom-conversion-service.xml | 2 +- 37 files changed, 418 insertions(+), 341 deletions(-) rename org.springframework.core/src/main/java/org/springframework/core/convert/{support => converter}/ConditionalGenericConverter.java (95%) rename org.springframework.core/src/main/java/org/springframework/core/convert/{support => converter}/ConverterMatcher.java (93%) rename org.springframework.core/src/main/java/org/springframework/core/convert/{support => converter}/GenericConverter.java (78%) create mode 100644 org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionServiceFactory.java delete mode 100644 org.springframework.core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java create mode 100644 org.springframework.core/src/main/java/org/springframework/core/convert/support/EntityConverter.java diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index 0e6e86e597..f4c896afba 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -16,6 +16,15 @@ package org.springframework.beans.factory; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.lang.reflect.Field; import java.net.MalformedURLException; import java.security.AccessControlContext; @@ -31,19 +40,12 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; + import javax.security.auth.Subject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import static org.junit.Assert.*; import org.junit.Test; -import test.beans.DerivedTestBean; -import test.beans.DummyFactory; -import test.beans.ITestBean; -import test.beans.LifecycleBean; -import test.beans.NestedTestBean; -import test.beans.TestBean; - import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.NotWritablePropertyException; @@ -72,11 +74,19 @@ import org.springframework.beans.factory.xml.DependenciesBean; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.core.MethodParameter; import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.convert.support.ConversionServiceFactory; +import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.util.StopWatch; +import test.beans.DerivedTestBean; +import test.beans.DummyFactory; +import test.beans.ITestBean; +import test.beans.LifecycleBean; +import test.beans.NestedTestBean; +import test.beans.TestBean; + /** * Tests properties population and autowire behavior. * @@ -831,7 +841,7 @@ public final class DefaultListableBeanFactoryTests { @Test public void testCustomConverter() { DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); - DefaultConversionService conversionService = new DefaultConversionService(); + GenericConversionService conversionService = (GenericConversionService) ConversionServiceFactory.createDefault(); conversionService.addConverter(new Converter() { public Float convert(String source) { try { diff --git a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java index cc0e6d342b..f2ee12774f 100644 --- a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java +++ b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionService.java @@ -24,11 +24,10 @@ import org.springframework.core.GenericTypeResolver; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.core.convert.converter.ConverterRegistry; -import org.springframework.core.convert.support.ConditionalGenericConverter; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.core.convert.support.GenericConversionService; -import org.springframework.core.convert.support.GenericConverter; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.format.AnnotationFormatterFactory; import org.springframework.format.Formatter; import org.springframework.format.FormatterRegistry; @@ -42,34 +41,18 @@ import org.springframework.format.Printer; */ public class FormattingConversionService implements FormatterRegistry, ConversionService { - private GenericConversionService conversionService = new GenericConversionService(); - - /** - * Creates a new FormattingConversionService, initially with no Formatters registered. - * A {@link DefaultConversionService} is configured as the parent conversion service to support primitive type conversion. - */ - public FormattingConversionService() { - this.conversionService.setParent(new DefaultConversionService()); - } - - /** - * Creates a new FormattingConversionService, initially with no Formatters registered. - * The conversion logic contained in the specified parent is merged with this service. - */ - public FormattingConversionService(ConversionService parent) { - this.conversionService.setParent(parent); - } + private ConversionService conversionService = ConversionServiceFactory.createDefault(); // implementing FormattingRegistry - + public void addFormatterForFieldType(Class fieldType, Printer printer, Parser parser) { - this.conversionService.addGenericConverter(fieldType, String.class, new PrinterConverter(printer, this.conversionService)); - this.conversionService.addGenericConverter(String.class, fieldType, new ParserConverter(parser, this.conversionService)); + getConverterRegistry().addGenericConverter(new PrinterConverter(fieldType, printer, this.conversionService)); + getConverterRegistry().addGenericConverter(new ParserConverter(fieldType, parser, this.conversionService)); } public void addFormatterForFieldType(Class fieldType, Formatter formatter) { - this.conversionService.addGenericConverter(fieldType, String.class, new PrinterConverter(formatter, this.conversionService)); - this.conversionService.addGenericConverter(String.class, fieldType, new ParserConverter(formatter, this.conversionService)); + getConverterRegistry().addGenericConverter(new PrinterConverter(fieldType, formatter, this.conversionService)); + getConverterRegistry().addGenericConverter(new ParserConverter(fieldType, formatter, this.conversionService)); } @SuppressWarnings("unchecked") @@ -83,25 +66,31 @@ public class FormattingConversionService implements FormatterRegistry, Conversio } Set> fieldTypes = annotationFormatterFactory.getFieldTypes(); for (final Class fieldType : fieldTypes) { - this.conversionService.addGenericConverter(fieldType, String.class, new ConditionalGenericConverter() { + getConverterRegistry().addGenericConverter(new ConditionalGenericConverter() { + public Class[][] getConvertibleTypes() { + return new Class[][] { { fieldType, String.class } }; + } public boolean matches(TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) { return sourceFieldType.getAnnotation(annotationType) != null; } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Printer printer = annotationFormatterFactory.getPrinter(sourceType.getAnnotation(annotationType), sourceType.getType()); - return new PrinterConverter(printer, conversionService).convert(source, sourceType, targetType); + return new PrinterConverter(fieldType, printer, conversionService).convert(source, sourceType, targetType); } public String toString() { return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + String.class.getName(); } }); - this.conversionService.addGenericConverter(String.class, fieldType, new ConditionalGenericConverter() { + getConverterRegistry().addGenericConverter(new ConditionalGenericConverter() { + public Class[][] getConvertibleTypes() { + return new Class[][] { { String.class, fieldType } }; + } public boolean matches(TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) { return targetFieldType.getAnnotation(annotationType) != null; } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Parser parser = annotationFormatterFactory.getParser(targetType.getAnnotation(annotationType), targetType.getType()); - return new ParserConverter(parser, conversionService).convert(source, sourceType, targetType); + return new ParserConverter(fieldType, parser, conversionService).convert(source, sourceType, targetType); } public String toString() { return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName(); @@ -111,7 +100,7 @@ public class FormattingConversionService implements FormatterRegistry, Conversio } public ConverterRegistry getConverterRegistry() { - return this.conversionService; + return (ConverterRegistry) this.conversionService; } // implementing ConverisonService @@ -146,6 +135,8 @@ public class FormattingConversionService implements FormatterRegistry, Conversio private static class PrinterConverter implements GenericConverter { + private Class fieldType; + private TypeDescriptor printerObjectType; @SuppressWarnings("unchecked") @@ -153,12 +144,17 @@ public class FormattingConversionService implements FormatterRegistry, Conversio private ConversionService conversionService; - public PrinterConverter(Printer printer, ConversionService conversionService) { + public PrinterConverter(Class fieldType, Printer printer, ConversionService conversionService) { + this.fieldType = fieldType; this.printerObjectType = TypeDescriptor.valueOf(resolvePrinterObjectType(printer)); this.printer = printer; this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { this.fieldType, String.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (!sourceType.isAssignableTo(this.printerObjectType)) { @@ -174,15 +170,22 @@ public class FormattingConversionService implements FormatterRegistry, Conversio private static class ParserConverter implements GenericConverter { + private Class fieldType; + private Parser parser; private ConversionService conversionService; - public ParserConverter(Parser parser, ConversionService conversionService) { + public ParserConverter(Class fieldType, Parser parser, ConversionService conversionService) { + this.fieldType = fieldType; this.parser = parser; this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { String.class, this.fieldType } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { String submittedValue = (String) source; if (submittedValue == null || submittedValue.length() == 0) { diff --git a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionServiceFactoryBean.java b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionServiceFactoryBean.java index 2134a0929d..8473f219f7 100644 --- a/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionServiceFactoryBean.java +++ b/org.springframework.context/src/main/java/org/springframework/format/support/FormattingConversionServiceFactoryBean.java @@ -30,18 +30,11 @@ import org.springframework.util.ClassUtils; */ public class FormattingConversionServiceFactoryBean implements FactoryBean, InitializingBean { - private ConversionService parent; - - private FormattingConversionService conversionService; - - public void setParent(ConversionService parent) { - this.parent = parent; - } - + private FormattingConversionService conversionService = new FormattingConversionService(); + // implementing InitializingBean public void afterPropertiesSet() { - initConversionService(); installNumberFormatting(); installJodaTimeFormattingIfPresent(); } @@ -62,14 +55,6 @@ public class FormattingConversionServiceFactoryBean implements FactoryBean@DateTimeFormat. * @author Keith Donald * @since 3.0 + * TODO - consider collapsing into ConditionalGenericConverter */ public interface ConverterMatcher { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterRegistry.java b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterRegistry.java index 8a8bee8014..1b29390098 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterRegistry.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterRegistry.java @@ -34,7 +34,15 @@ public interface ConverterRegistry { void addConverterFactory(ConverterFactory converterFactory); /** - * Remove the conversion logic for the sourceType to the targetType. + * Add a generic converter to this registry. + * @param sourceType the source type to convert from + * @param targetType the target type to convert to + * @param converter the generic converter + */ + void addGenericConverter(GenericConverter converter); + + /** + * Remove any converters from sourceType to targetType. * @param sourceType the source type * @param targetType the target type */ diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/GenericConverter.java similarity index 78% rename from org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConverter.java rename to org.springframework.core/src/main/java/org/springframework/core/convert/converter/GenericConverter.java index 142b9939a4..e7365e237c 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/converter/GenericConverter.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package org.springframework.core.convert.support; +package org.springframework.core.convert.converter; import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.ConverterFactory; +import org.springframework.core.convert.support.GenericConversionService; /** * Uniform converter interface as returned from {@link GenericConversionService#getConverter}. @@ -35,6 +34,13 @@ import org.springframework.core.convert.converter.ConverterFactory; */ public interface GenericConverter { + /** + * The source and target types this converter can convert between. + * Each entry in the returned array is a two-element array where the first element is a sourceType that can be converted from, + * and the second element is a targetType that can be converted to. + */ + public Class[][] getConvertibleTypes(); + /** * Convert the source to the targetType described by the TypeDescriptor. * @param source the source object to convert (may be null) diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayConverter.java index e495c863c2..6be42c31bb 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayConverter.java @@ -19,6 +19,7 @@ package org.springframework.core.convert.support; import static org.springframework.core.convert.support.ConversionUtils.asList; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a source array to a target array type. @@ -33,6 +34,10 @@ final class ArrayToArrayConverter implements GenericConverter { public ArrayToArrayConverter(GenericConversionService conversionService) { this.helperConverter = new CollectionToArrayConverter(conversionService); } + + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object[].class, Object[].class } }; + } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.convert(asList(source), sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java index 6a02f35672..3656684547 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.java @@ -24,6 +24,7 @@ import java.util.Collection; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from an array to a collection. @@ -39,6 +40,10 @@ final class ArrayToCollectionConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object[].class, Collection.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToMapConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToMapConverter.java index 18ae6bc4f7..c296721eef 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToMapConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToMapConverter.java @@ -18,7 +18,10 @@ package org.springframework.core.convert.support; import static org.springframework.core.convert.support.ConversionUtils.asList; +import java.util.Map; + import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from an array to a Map. @@ -34,6 +37,10 @@ final class ArrayToMapConverter implements GenericConverter { this.helperConverter = new CollectionToMapConverter(conversionService); } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object[].class, Map.class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.convert(asList(source), sourceType, targetType); } diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectConverter.java index 40c094bdb1..663eb32e70 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectConverter.java @@ -19,6 +19,7 @@ package org.springframework.core.convert.support; import static org.springframework.core.convert.support.ConversionUtils.asList; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from an array to a single Object. @@ -34,6 +35,10 @@ final class ArrayToObjectConverter implements GenericConverter { this.helperConverter = new CollectionToObjectConverter(conversionService); } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object[].class, Object.class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.convert(asList(source), sourceType, targetType); } diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayConverter.java index 639505afa1..93f0275ff2 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayConverter.java @@ -25,6 +25,7 @@ import java.util.Iterator; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Collection to an array. @@ -40,6 +41,10 @@ final class CollectionToArrayConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Collection.class, Object[].class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return this.conversionService.convertNullSource(sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionConverter.java index 57363b42fe..d177c6dcda 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionConverter.java @@ -24,6 +24,7 @@ import java.util.Collection; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a source Collection to target Collection type. @@ -39,6 +40,10 @@ final class CollectionToCollectionConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Collection.class, Collection.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToMapConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToMapConverter.java index 92811292c5..bd6c549d6f 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToMapConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToMapConverter.java @@ -23,7 +23,7 @@ import java.util.Map; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.style.StylerUtils; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Collection to a Map. @@ -39,6 +39,10 @@ final class CollectionToMapConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Collection.class, Map.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectConverter.java index 5d0a98ddd8..c5c8183d31 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectConverter.java @@ -23,6 +23,7 @@ import java.util.Collection; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Collection to a single Object. @@ -40,6 +41,10 @@ final class CollectionToObjectConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Collection.class, Object.class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return this.conversionService.convertNullSource(sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionServiceFactory.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionServiceFactory.java new file mode 100644 index 0000000000..e162857b80 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionServiceFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import org.springframework.core.convert.ConversionService; + +/** + * A factor for creating common ConversionService configurations. + * @author Keith Donald + * @since 3.0 + */ +public final class ConversionServiceFactory { + + private ConversionServiceFactory() { + + } + + /** + * Create a default ConversionService. + */ + public static ConversionService createDefault() { + GenericConversionService conversionService = new GenericConversionService(); + conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService)); + conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); + conversionService.addGenericConverter(new ArrayToMapConverter(conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); + conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); + conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService)); + conversionService.addGenericConverter(new CollectionToMapConverter(conversionService)); + conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); + conversionService.addGenericConverter(new MapToMapConverter(conversionService)); + conversionService.addGenericConverter(new MapToArrayConverter(conversionService)); + conversionService.addGenericConverter(new MapToCollectionConverter(conversionService)); + conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToMapConverter(conversionService)); + conversionService.addConverter(new StringToBooleanConverter()); + conversionService.addConverter(new StringToCharacterConverter()); + conversionService.addConverter(new StringToLocaleConverter()); + conversionService.addConverter(new NumberToCharacterConverter()); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + conversionService.addConverterFactory(new StringToEnumConverterFactory()); + conversionService.addConverterFactory(new NumberToNumberConverterFactory()); + conversionService.addConverterFactory(new CharacterToNumberFactory()); + conversionService.addConverter(new ObjectToStringConverter()); + conversionService.addGenericConverter(new ObjectToObjectGenericConverter()); + return conversionService; + } +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java index e18e24028d..382d0f3d52 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionUtils.java @@ -24,6 +24,7 @@ import java.util.RandomAccess; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; final class ConversionUtils { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java deleted file mode 100644 index 569376ff7a..0000000000 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/DefaultConversionService.java +++ /dev/null @@ -1,47 +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.Locale; - -/** - * Default implementation of a conversion service. Will automatically register from string - * converters for a number of standard Java types like Class, Number, Boolean and so on. - * - * @author Keith Donald - * @author Juergen Hoeller - * @since 3.0 - */ -public class DefaultConversionService extends GenericConversionService { - - /** - * Create a new default conversion service, installing the default converters. - */ - public DefaultConversionService() { - addConverter(String.class, Boolean.class, new StringToBooleanConverter()); - addConverter(String.class, Character.class, new StringToCharacterConverter()); - addConverter(String.class, Locale.class, new StringToLocaleConverter()); - addConverter(Number.class, Character.class, new NumberToCharacterConverter()); - addConverterFactory(String.class, Number.class, new StringToNumberConverterFactory()); - addConverterFactory(String.class, Enum.class, new StringToEnumConverterFactory()); - addConverterFactory(Number.class, Number.class, new NumberToNumberConverterFactory()); - addConverterFactory(Character.class, Number.class, new CharacterToNumberFactory()); - addConverter(Object.class, String.class, new ObjectToStringConverter()); - addGenericConverter(Object.class, Object.class, new ObjectToObjectGenericConverter()); - } - -} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/EntityConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/EntityConverter.java new file mode 100644 index 0000000000..4b96d0cd7d --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/EntityConverter.java @@ -0,0 +1,97 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.ConditionalGenericConverter; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; + +/** + * Converts an entity identifier to a entity reference by calling a static finder method on the target entity type. + * Also converts a entity reference to a String by printing its id property to String. + * For id-to-entity conversion to match, the finder method must be public, static, have the signature 'find[EntityName]([IdType])', and return an instance of the desired entity type. + * For entity-to-string conversion to match, a getter method for the 'id' property must be defined. + * @author Keith Donald + * @since 3.0 + */ +final class EntityConverter implements ConditionalGenericConverter { + + private ConversionService conversionService; + + public EntityConverter(ConversionService conversionService) { + this.conversionService = conversionService; + } + + public Class[][] getConvertibleTypes() { + return new Class[][] { + { Object.class, Object.class }, + { Object.class, String.class } + }; + } + + public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { + if (String.class.equals(targetType.getType())) { + return getIdAccessor(sourceType.getType()) != null; + } else { + return getFinder(targetType.getType()) != null; + } + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (String.class.equals(targetType.getType())) { + Method idAccessor = getIdAccessor(sourceType.getType()); + Object id = ReflectionUtils.invokeMethod(idAccessor, source); + return this.conversionService.convert(id, String.class); + } else { + Method finder = getFinder(targetType.getType()); + Object id = conversionService.convert(source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])); + return ReflectionUtils.invokeMethod(finder, source, id); + } + } + + private Method getIdAccessor(Class entityClass) { + return ClassUtils.getMethodIfAvailable(entityClass, "getId"); + } + + private Method getFinder(Class entityClass) { + String finderMethod = "find" + getEntityName(entityClass); + Method[] methods = entityClass.getDeclaredMethods(); + for (Method method : methods) { + if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1) { + if (method.getName().equals(finderMethod)) { + return method; + } + } + } + return null; + } + + private String getEntityName(Class entityClass) { + String shortName = ClassUtils.getShortName(entityClass); + int lastDot = shortName.lastIndexOf('.'); + if (lastDot != -1) { + return shortName.substring(lastDot + 1); + } else { + return shortName; + } + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index aae14371e8..9f051df699 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -19,12 +19,10 @@ 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; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; -import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,7 +33,9 @@ import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; +import org.springframework.core.convert.converter.ConverterMatcher; import org.springframework.core.convert.converter.ConverterRegistry; +import org.springframework.core.convert.converter.GenericConverter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -50,6 +50,10 @@ public class GenericConversionService implements ConversionService, ConverterReg private static final Log logger = LogFactory.getLog(GenericConversionService.class); private static final GenericConverter NO_OP_CONVERTER = new GenericConverter() { + public Class[][] getConvertibleTypes() { + return null; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return source; } @@ -57,68 +61,6 @@ public class GenericConversionService implements ConversionService, ConverterReg private final Map, Map, MatchableConverters>> converters = new HashMap, Map, MatchableConverters>>(36); - private ConversionService parent; - - private GenericConverter parentConverterAdapter = new GenericConverter() { - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - return parent.convert(source, sourceType, targetType); - } - }; - - public GenericConversionService() { - addGenericConverter(Object[].class, Object[].class, new ArrayToArrayConverter(this)); - addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter(this)); - addGenericConverter(Object[].class, Map.class, new ArrayToMapConverter(this)); - addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter(this)); - addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter(this)); - addGenericConverter(Collection.class, Object[].class, new CollectionToArrayConverter(this)); - addGenericConverter(Collection.class, Map.class, new CollectionToMapConverter(this)); - addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter(this)); - addGenericConverter(Map.class, Map.class, new MapToMapConverter(this)); - addGenericConverter(Map.class, Object[].class, new MapToArrayConverter(this)); - addGenericConverter(Map.class, Collection.class, new MapToCollectionConverter(this)); - addGenericConverter(Map.class, Object.class, new MapToObjectConverter(this)); - addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter(this)); - addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter(this)); - addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(this)); - } - - /** - * Registers the converters in the set provided. - * JavaBean-friendly alternative to calling {@link #addConverter(Converter)}. - * @see #addConverter(Converter) - */ - public void setConverters(Set> converters) { - for (Converter converter : converters) { - addConverter(converter); - } - } - - /** - * Registers the converter factories in the set provided. - * JavaBean-friendly alternative to calling {@link #addConverterFactory(ConverterFactory)}. - * @see #addConverterFactory(ConverterFactory) - */ - public void setConverterFactories(Set> converters) { - for (ConverterFactory converterFactory : converters) { - addConverterFactory(converterFactory); - } - } - - /** - * Set the parent of this conversion service. This is optional. - */ - public void setParent(ConversionService parent) { - this.parent = parent; - } - - /** - * Returns the parent of this conversion service. May be null. - */ - public ConversionService getParent() { - return this.parent; - } - // implementing ConverterRegistry public void addConverter(Converter converter) { @@ -127,9 +69,7 @@ public class GenericConversionService implements ConversionService, ConverterReg throw new IllegalArgumentException( "Unable to the determine sourceType and targetType your Converter converts between; declare these types or implement ConverterInfo"); } - Class sourceType = typeInfo[0]; - Class targetType = typeInfo[1]; - addConverter(sourceType, targetType, converter); + addGenericConverter(new ConverterAdapter(typeInfo, converter)); } public void addConverterFactory(ConverterFactory converterFactory) { @@ -138,11 +78,16 @@ public class GenericConversionService implements ConversionService, ConverterReg throw new IllegalArgumentException( "Unable to the determine sourceType and targetRangeType R your ConverterFactory converts between; declare these types or implement ConverterInfo"); } - Class sourceType = typeInfo[0]; - Class targetType = typeInfo[1]; - addConverterFactory(sourceType, targetType, converterFactory); + addGenericConverter(new ConverterFactoryAdapter(typeInfo, converterFactory)); } + public void addGenericConverter(GenericConverter converter) { + Class[][] convertibleTypes = converter.getConvertibleTypes(); + for (Class[] convertibleType : convertibleTypes) { + getMatchableConvertersList(convertibleType[0], convertibleType[1]).add(converter); + } + } + public void removeConvertible(Class sourceType, Class targetType) { getSourceConverterMap(sourceType).remove(targetType); } @@ -182,50 +127,6 @@ public class GenericConversionService implements ConversionService, ConverterReg return invokeConverter(converter, source, sourceType, targetType); } - /** - * Registers a GenericConverter for the source/target type pair. - * @param sourceType the source type to convert from - * @param targetType the target type to convert to - * @param converter the generic converter. - */ - public void addGenericConverter(Class sourceType, Class targetType, GenericConverter converter) { - getMatchableConvertersList(sourceType, targetType).add(converter); - } - - /** - * Registers a GenericConverter for the source/target type pair that will only be matched if the provided matcher returns true. - * @param sourceType the source type to convert from - * @param targetType the target type to convert to - * @param matcher a matcher can restrict a match of the converter based on source and target runtime field types - * @param converter the generic converter. - */ - public void addGenericConverter(Class sourceType, Class targetType, GenericConverter converter, - ConverterMatcher matcher) { - getMatchableConvertersList(sourceType, targetType).add(matcher, converter); - } - - /** - * Registers a Converter with the sourceType and targetType to index on specified explicitly. - * This method performs better than {@link #addConverter(Converter)} because there parameterized types S and T don't have to be discovered. - * @param sourceType the source type to convert from - * @param targetType the target type to convert to - * @param converter the converter. - */ - public void addConverter(Class sourceType, Class targetType, Converter converter) { - addGenericConverter(sourceType, targetType, new ConverterAdapter(converter)); - } - - /** - * Registers a ConverterFactory with the sourceType and targetType to index on specified explicitly. - * This method performs better than {@link #addConverter(ConverterFactory)} because there parameterized types S and T don't have to be discovered. - * @param sourceType the source type to convert from - * @param targetType the target type to convert to - * @param converter the converter.factory - */ - public void addConverterFactory(Class sourceType, Class targetType, ConverterFactory converterFactory) { - addGenericConverter(sourceType, targetType, new ConverterFactoryAdapter(converterFactory)); - } - public String toString() { StringBuilder builder = new StringBuilder(); builder.append("ConversionService converters = ").append("\n"); @@ -236,9 +137,6 @@ public class GenericConversionService implements ConversionService, ConverterReg builder.append("\n"); } } - if (this.parent != null) { - builder.append("parent = ").append(this.parent); - } return builder.toString(); } @@ -275,8 +173,6 @@ public class GenericConversionService implements ConversionService, ConverterReg GenericConverter converter = findConverterForClassPair(sourceType, targetType); if (converter != null) { return converter; - } else if (this.parent != null && this.parent.canConvert(sourceType, targetType)) { - return this.parentConverterAdapter; } else { return getDefaultConverter(sourceType, targetType); } @@ -443,10 +339,17 @@ public class GenericConversionService implements ConversionService, ConverterReg @SuppressWarnings("unchecked") private final class ConverterAdapter implements GenericConverter { + private final Class[] typeInfo; + private final Converter converter; - public ConverterAdapter(Converter converter) { + public ConverterAdapter(Class[] typeInfo, Converter converter) { this.converter = converter; + this.typeInfo = typeInfo; + } + + public Class[][] getConvertibleTypes() { + return new Class[][] { this.typeInfo }; } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { @@ -464,12 +367,19 @@ public class GenericConversionService implements ConversionService, ConverterReg @SuppressWarnings("unchecked") private final class ConverterFactoryAdapter implements GenericConverter { + private final Class[] typeInfo; + private final ConverterFactory converterFactory; - public ConverterFactoryAdapter(ConverterFactory converterFactory) { + public ConverterFactoryAdapter(Class[] typeInfo, ConverterFactory converterFactory) { this.converterFactory = converterFactory; + this.typeInfo = typeInfo; } + public Class[][] getConvertibleTypes() { + return new Class[][] { this.typeInfo }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return convertNullSource(sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapEntryConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapEntryConverter.java index 2cce280edd..d3ee377f8a 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapEntryConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapEntryConverter.java @@ -20,6 +20,7 @@ import static org.springframework.core.convert.support.ConversionUtils.invokeCon import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Helper for converting map entries. diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToArrayConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToArrayConverter.java index 9316c58c59..ccd40d3523 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToArrayConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToArrayConverter.java @@ -17,8 +17,10 @@ package org.springframework.core.convert.support; import java.util.List; +import java.util.Map; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Map to an array. @@ -37,6 +39,10 @@ final class MapToArrayConverter implements GenericConverter { this.collectionToArrayHelperConverter = new CollectionToArrayConverter(conversionService); } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Map.class, Object[].class } }; + } + 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); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToCollectionConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToCollectionConverter.java index 9c7c042e48..aef33be5d5 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToCollectionConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToCollectionConverter.java @@ -23,6 +23,7 @@ import java.util.Map; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Map to a Collection. @@ -38,6 +39,10 @@ final class MapToCollectionConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Map.class, Collection.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java index 87892d9a4a..e0999cc988 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java @@ -22,6 +22,7 @@ import java.util.Map; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a source Map to a target Map type. @@ -37,6 +38,10 @@ final class MapToMapConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Map.class, Map.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToObjectConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToObjectConverter.java index 62691fdf38..2ee7a6bd7f 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToObjectConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToObjectConverter.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Properties; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a Map to a single Object. @@ -39,6 +40,10 @@ final class MapToObjectConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Map.class, Object.class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return this.conversionService.convertNullSource(sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayConverter.java index b4faccb4ad..305072e6ab 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayConverter.java @@ -22,6 +22,7 @@ import java.lang.reflect.Array; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; import org.springframework.util.StringUtils; /** @@ -38,6 +39,10 @@ final class ObjectToArrayConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object.class, Object[].class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return this.conversionService.convertNullSource(sourceType, targetType); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionConverter.java index 17ab69e827..f0107e0e1c 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionConverter.java @@ -23,6 +23,7 @@ import java.util.Collection; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; import org.springframework.util.StringUtils; /** @@ -39,6 +40,10 @@ final class ObjectToCollectionConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object.class, Collection.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToMapConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToMapConverter.java index a1334ad4ff..1b4200a5af 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToMapConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToMapConverter.java @@ -22,6 +22,7 @@ import java.util.Properties; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; /** * Converts from a single Object to a Map. @@ -37,6 +38,10 @@ final class ObjectToMapConverter implements GenericConverter { this.conversionService = conversionService; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object.class, Map.class } }; + } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToObjectGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToObjectGenericConverter.java index 998ed1413b..3c1d2487eb 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToObjectGenericConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToObjectGenericConverter.java @@ -22,6 +22,7 @@ import java.lang.reflect.Method; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; @@ -42,6 +43,10 @@ final class ObjectToObjectGenericConverter implements ConditionalGenericConverte return getValueOfMethodOn(targetClass, sourceClass) != null || getConstructor(targetClass, sourceClass) != null; } + public Class[][] getConvertibleTypes() { + return new Class[][] { { Object.class, Object.class } }; + } + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (sourceType.isAssignableTo(targetType)) { return source; diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/support/DefaultConversionServiceTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/support/DefaultConversionServiceTests.java index f0c5447f1d..2bc8fda9e6 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/support/DefaultConversionServiceTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/support/DefaultConversionServiceTests.java @@ -24,7 +24,7 @@ import java.math.BigInteger; import java.util.Locale; 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.converter.Converter; @@ -186,20 +186,20 @@ public class DefaultConversionServiceTests { @Test public void convertObjectToObjectValueOFMethod() { - DefaultConversionService conversionService = new DefaultConversionService(); + ConversionService conversionService = ConversionServiceFactory.createDefault(); assertEquals(new Integer(3), conversionService.convert("3", Integer.class)); } @Test public void convertObjectToObjectConstructor() { - DefaultConversionService conversionService = new DefaultConversionService(); + ConversionService conversionService = ConversionServiceFactory.createDefault(); assertEquals(new SSN("123456789"), conversionService.convert("123456789", SSN.class)); assertEquals("123456789", conversionService.convert(new SSN("123456789"), String.class)); } @Test(expected=ConverterNotFoundException.class) public void convertObjectToObjectNoValueOFMethodOrConstructor() { - DefaultConversionService conversionService = new DefaultConversionService(); + ConversionService conversionService = ConversionServiceFactory.createDefault(); conversionService.convert(new Long(3), SSN.class); } diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java index ad6c1c9851..e0bec9442f 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java @@ -146,8 +146,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToArray() { - conversionService.addGenericConverter(Object[].class, Object[].class, new ArrayToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); Integer[] result = conversionService.convert(new String[] { "1", "2", "3" }, Integer[].class); assertEquals(new Integer(1), result[0]); @@ -157,8 +156,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToPrimitiveArray() { - conversionService.addGenericConverter(Object[].class, Object[].class, new ArrayToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToArrayConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); int[] result = conversionService.convert(new String[] { "1", "2", "3" }, int[].class); assertEquals(1, result[0]); @@ -176,8 +174,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToListInterface() { - conversionService.addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); List result = conversionService.convert(new String[] { "1", "2", "3" }, List.class); assertEquals("1", result.get(0)); assertEquals("2", result.get(1)); @@ -188,8 +185,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToListGenericTypeConversion() throws Exception { - conversionService.addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); List result = (List) conversionService.convert(new String[] { "1", "2", "3" }, TypeDescriptor .valueOf(String[].class), new TypeDescriptor(getClass().getDeclaredField("genericList"))); @@ -200,8 +196,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToListImpl() { - conversionService.addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); LinkedList result = conversionService.convert(new String[] { "1", "2", "3" }, LinkedList.class); assertEquals("1", result.get(0)); assertEquals("2", result.get(1)); @@ -210,14 +205,13 @@ public class GenericConversionServiceTests { @Test(expected = ConversionFailedException.class) public void convertArrayToAbstractList() { - conversionService.addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToCollectionConverter(conversionService)); conversionService.convert(new String[] { "1", "2", "3" }, AbstractList.class); } @Test public void convertArrayToMap() { - conversionService.addGenericConverter(Object[].class, Map.class, new ArrayToMapConverter(conversionService)); + conversionService.addGenericConverter(new ArrayToMapConverter(conversionService)); Map result = conversionService.convert(new String[] { "foo=bar", "bar=baz", "baz=boop" }, Map.class); assertEquals("bar", result.get("foo")); assertEquals("baz", result.get("bar")); @@ -226,7 +220,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToMapWithElementConversion() throws Exception { - conversionService.addGenericConverter(Object[].class, Map.class, new ArrayToMapConverter(conversionService)); + conversionService.addGenericConverter(new ArrayToMapConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToEnumConverterFactory()); Map result = (Map) conversionService.convert(new String[] { "1=BAR", "2=BAZ" }, TypeDescriptor @@ -237,16 +231,14 @@ public class GenericConversionServiceTests { @Test public void convertArrayToString() { - conversionService.addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); String result = conversionService.convert(new String[] { "1", "2", "3" }, String.class); assertEquals("1,2,3", result); } @Test public void convertArrayToStringWithElementConversion() { - conversionService.addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); conversionService.addConverter(new ObjectToStringConverter()); String result = conversionService.convert(new Integer[] { 1, 2, 3 }, String.class); assertEquals("1,2,3", result); @@ -254,16 +246,14 @@ public class GenericConversionServiceTests { @Test public void convertEmptyArrayToString() { - conversionService.addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); String result = conversionService.convert(new String[0], String.class); assertEquals("", result); } @Test public void convertArrayToObject() { - conversionService.addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); Object[] array = new Object[] { 3L }; Object result = conversionService.convert(array, Object.class); assertEquals(3L, result); @@ -271,8 +261,7 @@ public class GenericConversionServiceTests { @Test public void convertArrayToObjectWithElementConversion() { - conversionService.addGenericConverter(Object[].class, Object.class, new ArrayToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new ArrayToObjectConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); String[] array = new String[] { "3" }; Integer result = conversionService.convert(array, Integer.class); @@ -281,8 +270,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToArray() { - conversionService.addGenericConverter(Collection.class, Object[].class, new CollectionToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService)); List list = new ArrayList(); list.add("1"); list.add("2"); @@ -295,8 +283,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToArrayWithElementConversion() { - conversionService.addGenericConverter(Collection.class, Object[].class, new CollectionToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToArrayConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); List list = new ArrayList(); list.add("1"); @@ -310,8 +297,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToCollection() throws Exception { - conversionService.addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); Set foo = new LinkedHashSet(); foo.add("1"); @@ -326,8 +312,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToCollectionNull() throws Exception { - conversionService.addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); List bar = (List) conversionService.convert(null, TypeDescriptor.valueOf(LinkedHashSet.class), new TypeDescriptor(getClass().getField("genericList"))); assertNull(bar); @@ -335,8 +320,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToCollectionNotGeneric() throws Exception { - conversionService.addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); Set foo = new LinkedHashSet(); foo.add("1"); @@ -351,8 +335,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToCollectionSpecialCaseSourceImpl() throws Exception { - conversionService.addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); Map map = new LinkedHashMap(); map.put("1", "1"); @@ -369,8 +352,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToMap() { - conversionService.addGenericConverter(Collection.class, Map.class, new CollectionToMapConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToMapConverter(conversionService)); List list = new ArrayList(); list.add("foo=bar"); list.add("bar=baz"); @@ -383,8 +365,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToMapWithElementConversion() throws Exception { - conversionService.addGenericConverter(Collection.class, Map.class, new CollectionToMapConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToMapConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToEnumConverterFactory()); List list = new ArrayList(); @@ -398,8 +379,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToString() { - conversionService.addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); List list = Arrays.asList(new String[] { "foo", "bar" }); String result = conversionService.convert(list, String.class); assertEquals("foo,bar", result); @@ -407,8 +387,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToStringWithElementConversion() throws Exception { - conversionService.addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); conversionService.addConverter(new ObjectToStringConverter()); List list = Arrays.asList(new Integer[] { 3, 5 }); String result = (String) conversionService.convert(list, @@ -418,8 +397,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToObject() { - conversionService.addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); List list = Collections.singletonList(3L); Long result = conversionService.convert(list, Long.class); assertEquals(new Long(3), result); @@ -427,8 +405,7 @@ public class GenericConversionServiceTests { @Test public void convertCollectionToObjectWithElementConversion() { - conversionService.addGenericConverter(Collection.class, Object.class, new CollectionToObjectConverter( - conversionService)); + conversionService.addGenericConverter(new CollectionToObjectConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); List list = Collections.singletonList("3"); Integer result = conversionService.convert(list, Integer.class); @@ -439,7 +416,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToMap() throws Exception { - conversionService.addGenericConverter(Map.class, Map.class, new MapToMapConverter(conversionService)); + conversionService.addGenericConverter(new MapToMapConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToEnumConverterFactory()); Map foo = new HashMap(); @@ -453,7 +430,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToStringArray() throws Exception { - conversionService.addGenericConverter(Map.class, Object[].class, new MapToArrayConverter(conversionService)); + conversionService.addGenericConverter(new MapToArrayConverter(conversionService)); Map foo = new LinkedHashMap(); foo.put("1", "BAR"); foo.put("2", "BAZ"); @@ -464,7 +441,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToStringArrayWithElementConversion() throws Exception { - conversionService.addGenericConverter(Map.class, Object[].class, new MapToArrayConverter(conversionService)); + conversionService.addGenericConverter(new MapToArrayConverter(conversionService)); conversionService.addConverter(new ObjectToStringConverter()); Map foo = new LinkedHashMap(); foo.put(1, FooEnum.BAR); @@ -477,7 +454,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToString() { - conversionService.addGenericConverter(Map.class, Object.class, new MapToObjectConverter(conversionService)); + conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); Map foo = new LinkedHashMap(); foo.put("1", "BAR"); foo.put("2", "BAZ"); @@ -489,7 +466,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToStringWithConversion() throws Exception { - conversionService.addGenericConverter(Map.class, Object.class, new MapToObjectConverter(conversionService)); + conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); Map foo = new LinkedHashMap(); foo.put(1, FooEnum.BAR); foo.put(2, FooEnum.BAZ); @@ -502,7 +479,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToObject() { - conversionService.addGenericConverter(Map.class, Object.class, new MapToObjectConverter(conversionService)); + conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); Map foo = new LinkedHashMap(); foo.put(1L, 1L); foo.put(2L, 2L); @@ -514,7 +491,7 @@ public class GenericConversionServiceTests { @Test public void convertMapToObjectWithConversion() throws Exception { - conversionService.addGenericConverter(Map.class, Object.class, new MapToObjectConverter(conversionService)); + conversionService.addGenericConverter(new MapToObjectConverter(conversionService)); conversionService.addConverterFactory(new NumberToNumberConverterFactory()); Map foo = new LinkedHashMap(); foo.put(1L, 1L); @@ -526,8 +503,7 @@ public class GenericConversionServiceTests { @Test public void convertStringToArray() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); String[] result = conversionService.convert("1,2,3", String[].class); assertEquals(3, result.length); assertEquals("1", result[0]); @@ -537,8 +513,7 @@ public class GenericConversionServiceTests { @Test public void convertStringToArrayWithElementConversion() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); Integer[] result = conversionService.convert("1,2,3", Integer[].class); assertEquals(3, result.length); @@ -549,16 +524,14 @@ public class GenericConversionServiceTests { @Test public void convertEmptyStringToArray() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); String[] result = conversionService.convert("", String[].class); assertEquals(0, result.length); } @Test public void convertObjectToArray() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); Object[] result = conversionService.convert(3L, Object[].class); assertEquals(1, result.length); assertEquals(3L, result[0]); @@ -566,8 +539,7 @@ public class GenericConversionServiceTests { @Test public void convertObjectToArrayWithElementConversion() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); conversionService.addConverterFactory(new NumberToNumberConverterFactory()); Integer[] result = conversionService.convert(3L, Integer[].class); assertEquals(1, result.length); @@ -576,8 +548,7 @@ public class GenericConversionServiceTests { @Test public void convertStringToCollection() { - conversionService.addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); List result = conversionService.convert("1,2,3", List.class); assertEquals(3, result.size()); assertEquals("1", result.get(0)); @@ -587,8 +558,7 @@ public class GenericConversionServiceTests { @Test public void convertStringToCollectionWithElementConversion() throws Exception { - conversionService.addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); List result = (List) conversionService.convert("1,2,3", TypeDescriptor.valueOf(String.class), new TypeDescriptor(getClass().getField("genericList"))); @@ -600,16 +570,14 @@ public class GenericConversionServiceTests { @Test public void convertEmptyStringToCollection() { - conversionService.addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); Collection result = conversionService.convert("", Collection.class); assertEquals(0, result.size()); } @Test public void convertObjectToCollection() { - conversionService.addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); List result = (List) conversionService.convert(3L, List.class); assertEquals(1, result.size()); assertEquals(3L, result.get(0)); @@ -617,8 +585,7 @@ public class GenericConversionServiceTests { @Test public void convertObjectToCollectionWithElementConversion() throws Exception { - conversionService.addGenericConverter(Object.class, Collection.class, new ObjectToCollectionConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToCollectionConverter(conversionService)); conversionService.addConverterFactory(new NumberToNumberConverterFactory()); List result = (List) conversionService.convert(3L, TypeDescriptor.valueOf(Long.class), new TypeDescriptor(getClass().getField("genericList"))); @@ -628,7 +595,8 @@ public class GenericConversionServiceTests { @Test public void convertStringToMap() { - conversionService.addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new MapToMapConverter(conversionService)); Map result = conversionService.convert(" foo=bar\n bar=baz\n baz=boop", Map.class); assertEquals("bar", result.get("foo")); assertEquals("baz", result.get("bar")); @@ -637,7 +605,8 @@ public class GenericConversionServiceTests { @Test public void convertStringToMapWithElementConversion() throws Exception { - conversionService.addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new MapToMapConverter(conversionService)); conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToEnumConverterFactory()); Map result = (Map) conversionService.convert("1=BAR\n 2=BAZ", TypeDescriptor.valueOf(String.class), @@ -648,14 +617,14 @@ public class GenericConversionServiceTests { @Test public void convertObjectToMap() { - conversionService.addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToMapConverter(conversionService)); Map result = conversionService.convert(new Integer(3), Map.class); assertEquals(new Integer(3), result.get(new Integer(3))); } @Test public void convertObjectToMapWithConversion() throws Exception { - conversionService.addGenericConverter(Object.class, Map.class, new ObjectToMapConverter(conversionService)); + conversionService.addGenericConverter(new ObjectToMapConverter(conversionService)); conversionService.addConverterFactory(new NumberToNumberConverterFactory()); Map result = (Map) conversionService.convert(1L, TypeDescriptor.valueOf(Integer.class), new TypeDescriptor( getClass().getField("genericMap2"))); @@ -664,8 +633,7 @@ public class GenericConversionServiceTests { @Test public void genericConverterDelegatingBackToConversionServiceConverterNotFound() { - conversionService.addGenericConverter(Object.class, Object[].class, new ObjectToArrayConverter( - conversionService)); + conversionService.addGenericConverter(new ObjectToArrayConverter(conversionService)); try { conversionService.convert("1", Integer[].class); } catch (ConversionFailedException e) { @@ -673,18 +641,6 @@ public class GenericConversionServiceTests { } } - @Test - public void parent() { - GenericConversionService parent = new GenericConversionService(); - conversionService.setParent(parent); - assertFalse(conversionService.canConvert(String.class, Integer.class)); - try { - conversionService.convert("3", Integer.class); - } catch (ConverterNotFoundException e) { - - } - } - public static enum FooEnum { BAR, BAZ } diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index ea366c2178..cd5529ab6c 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -20,7 +20,7 @@ import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.expression.EvaluationException; import org.springframework.expression.TypeConverter; import org.springframework.expression.spel.SpelEvaluationException; @@ -40,7 +40,7 @@ public class StandardTypeConverter implements TypeConverter { private final ConversionService conversionService; public StandardTypeConverter() { - this.conversionService = new DefaultConversionService(); + this.conversionService = ConversionServiceFactory.createDefault(); } public StandardTypeConverter(ConversionService conversionService) { diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java index cbed2bd868..e8d220b44d 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java @@ -23,8 +23,9 @@ import junit.framework.Assert; import org.junit.Before; import org.junit.Test; +import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; import org.springframework.expression.TypeConverter; @@ -98,7 +99,7 @@ public class ExpressionTestsUsingCoreConversionService extends ExpressionTestCas */ private static class TypeConvertorUsingConversionService implements TypeConverter { - private final DefaultConversionService service = new DefaultConversionService(); + private final ConversionService service = ConversionServiceFactory.createDefault(); public boolean canConvert(Class sourceType, Class targetType) { return this.service.canConvert(sourceType, targetType); diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java index 36b7d41f55..f523af99a5 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/support/StandardComponentsTests.java @@ -20,9 +20,7 @@ import java.util.List; import org.junit.Assert; import org.junit.Test; - import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.expression.EvaluationException; import org.springframework.expression.Operation; import org.springframework.expression.OperatorOverloader; @@ -73,7 +71,7 @@ public class StandardComponentsTests { @Test public void testStandardTypeConverter() throws EvaluationException { - TypeConverter tc = new StandardTypeConverter(new DefaultConversionService()); + TypeConverter tc = new StandardTypeConverter(); tc.convertValue(3, TypeDescriptor.valueOf(Double.class)); } diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index 1b9a905222..7403c74a30 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -13,7 +13,6 @@ import javax.validation.constraints.NotNull; import org.junit.Before; import org.junit.Test; -import org.springframework.beans.ConversionNotSupportedException; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.convert.ConversionFailedException; diff --git a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-custom-conversion-service.xml b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-custom-conversion-service.xml index 334c20d7f9..82f08d8895 100644 --- a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-custom-conversion-service.xml +++ b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config-custom-conversion-service.xml @@ -7,6 +7,6 @@ - +