diff --git a/org.springframework.context/src/main/java/org/springframework/ui/format/support/FormattingConversionServiceAdapter.java b/org.springframework.context/src/main/java/org/springframework/ui/format/support/FormattingConversionServiceAdapter.java index 4750024ad4d..a6483e8a1bb 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/format/support/FormattingConversionServiceAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/format/support/FormattingConversionServiceAdapter.java @@ -76,10 +76,6 @@ public class FormattingConversionServiceAdapter extends GenericConversionService this.formatter = formatter; } - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Should not be called"); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { try { return this.formatter.parse((String) source, LocaleContextHolder.getLocale()); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayGenericConverter.java new file mode 100644 index 00000000000..a272cfb725d --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayGenericConverter.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import java.lang.reflect.Array; + +import org.springframework.core.convert.TypeDescriptor; + +class ArrayToArrayGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public ArrayToArrayGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (sourceType.isAssignableTo(targetType)) { + return source; + } + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + Object target = Array.newInstance(targetElementType.getType(), Array.getLength(source)); + GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); + for (int i = 0; i < Array.getLength(target); i++) { + Array.set(target, i, converter.convert(Array.get(source, i), sourceElementType, targetElementType)); + } + return target; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionGenericConverter.java new file mode 100644 index 00000000000..c5862eb5d2a --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionGenericConverter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import java.lang.reflect.Array; +import java.util.Collection; + +import org.springframework.core.CollectionFactory; +import org.springframework.core.convert.TypeDescriptor; + +class ArrayToCollectionGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public ArrayToCollectionGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + int length = Array.getLength(source); + Collection collection = CollectionFactory.createCollection(targetType.getType(), length); + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + if (targetElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { + for (int i = 0; i < length; i++) { + collection.add(Array.get(source, i)); + } + } else { + GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); + for (int i = 0; i < length; i++) { + collection.add(converter.convert(Array.get(source, i), sourceElementType, targetElementType)); + } + } + return collection; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectGenericConverter.java new file mode 100644 index 00000000000..7cb909c92ec --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectGenericConverter.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import org.springframework.core.convert.TypeDescriptor; + +class ArrayToObjectGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public ArrayToObjectGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionGenericConverter.java deleted file mode 100644 index a7f88072f77..00000000000 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionGenericConverter.java +++ /dev/null @@ -1,197 +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.lang.reflect.Array; -import java.util.Collection; -import java.util.Iterator; - -import org.springframework.core.CollectionFactory; -import org.springframework.core.convert.TypeDescriptor; - -class CollectionGenericConverter implements GenericConverter { - - private GenericConversionService conversionService; - - public CollectionGenericConverter(GenericConversionService conversionService) { - this.conversionService = conversionService; - } - - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isArray() || targetType.isArray() || sourceType.isCollection() || targetType.isCollection(); - } - - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - if (isArrayToArray(sourceType, targetType)) { - return convertArrayToArray(source, sourceType, targetType); - } else if (isArrayToCollection(sourceType, targetType)) { - return convertArrayToCollection(source, sourceType, targetType); - } else if (isCollectionToCollection(sourceType, targetType)) { - return convertCollectionToCollection(source, sourceType, targetType); - } else if (isCollectionToArray(sourceType, targetType)) { - return convertCollectionToArray(source, sourceType, targetType); - } else if (isArrayToObject(sourceType, targetType)) { - return convertArrayToObject(source, sourceType, targetType); - } else if (isObjectToArray(sourceType, targetType)) { - return convertObjectToArray(source, sourceType, targetType); - } else if (isCollectionToObject(sourceType, targetType)) { - return convertCollectionToObject(source, sourceType, targetType); - } else { - return convertObjectToCollection(source, sourceType, targetType); - } - } - - private boolean isArrayToArray(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isArray() && targetType.isArray(); - } - - private Object convertArrayToArray(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - if (sourceType.isAssignableTo(targetType)) { - return source; - } - TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); - TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); - Object target = Array.newInstance(targetElementType.getType(), Array.getLength(source)); - GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); - for (int i = 0; i < Array.getLength(target); i++) { - Array.set(target, i, converter.convert(Array.get(source, i), sourceElementType, targetElementType)); - } - return target; - } - - private boolean isArrayToCollection(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isArray() && targetType.isCollection(); - } - - private Object convertArrayToCollection(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - int length = Array.getLength(source); - Collection collection = CollectionFactory.createCollection(targetType.getType(), length); - TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); - TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); - if (targetElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { - for (int i = 0; i < length; i++) { - collection.add(Array.get(source, i)); - } - } else { - GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); - for (int i = 0; i < length; i++) { - collection.add(converter.convert(Array.get(source, i), sourceElementType, targetElementType)); - } - } - return collection; - } - - private boolean isCollectionToArray(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isCollection() && targetType.isArray(); - } - - private Object convertCollectionToArray(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - Collection sourceCollection = (Collection) source; - TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); - if (sourceElementType == TypeDescriptor.NULL) { - sourceElementType = getElementType(sourceCollection); - } - TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); - Object array = Array.newInstance(targetElementType.getType(), sourceCollection.size()); - int i = 0; - if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { - for (Iterator it = sourceCollection.iterator(); it.hasNext(); i++) { - Array.set(array, i, it.next()); - } - } else { - GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); - for (Iterator it = sourceCollection.iterator(); it.hasNext(); i++) { - Array.set(array, i, converter.convert(it.next(), sourceElementType, targetElementType)); - } - } - return array; - } - - private boolean isCollectionToCollection(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isCollection() && targetType.isCollection(); - } - - public Object convertCollectionToCollection(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - Collection sourceCollection = (Collection) source; - TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); - if (sourceElementType == TypeDescriptor.NULL) { - sourceElementType = getElementType(sourceCollection); - } - TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); - if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { - if (sourceType.isAssignableTo(targetType)) { - return sourceCollection; - } else { - Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); - targetCollection.addAll(sourceCollection); - return targetCollection; - } - } - Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); - GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); - for (Object element : sourceCollection) { - targetCollection.add(converter.convert(element, sourceElementType, targetElementType)); - } - return targetCollection; - } - - private TypeDescriptor getElementType(Collection collection) { - for (Object element : collection) { - if (element != null) { - return TypeDescriptor.valueOf(element.getClass()); - } - } - return TypeDescriptor.NULL; - } - - private boolean isArrayToObject(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isArray(); - } - - private Object convertArrayToObject(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - private boolean isObjectToArray(TypeDescriptor sourceType, TypeDescriptor targetType) { - return targetType.isArray(); - } - - private Object convertObjectToArray(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); - Object array = Array.newInstance(targetType.getElementType(), 1); - if (sourceType.isAssignableTo(targetElementType)) { - Array.set(array, 0, source); - } else { - GenericConverter converter = conversionService.getConverter(sourceType, targetElementType); - Array.set(array, 0, converter.convert(source, sourceType, targetElementType)); - } - return array; - } - - private boolean isCollectionToObject(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isCollection(); - } - - private Object convertCollectionToObject(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - private Object convertObjectToCollection(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Not yet implemented"); - } - -} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayGenericConverter.java new file mode 100644 index 00000000000..7b8816a7452 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayGenericConverter.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 java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; + +import org.springframework.core.convert.TypeDescriptor; + +class CollectionToArrayGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public CollectionToArrayGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + Collection sourceCollection = (Collection) source; + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + if (sourceElementType == TypeDescriptor.NULL) { + sourceElementType = getElementType(sourceCollection); + } + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + Object array = Array.newInstance(targetElementType.getType(), sourceCollection.size()); + int i = 0; + if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { + for (Iterator it = sourceCollection.iterator(); it.hasNext(); i++) { + Array.set(array, i, it.next()); + } + } else { + GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); + for (Iterator it = sourceCollection.iterator(); it.hasNext(); i++) { + Array.set(array, i, converter.convert(it.next(), sourceElementType, targetElementType)); + } + } + return array; + } + + private TypeDescriptor getElementType(Collection collection) { + for (Object element : collection) { + if (element != null) { + return TypeDescriptor.valueOf(element.getClass()); + } + } + return TypeDescriptor.NULL; + } + +} diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionGenericConverter.java new file mode 100644 index 00000000000..79435e0a47e --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionGenericConverter.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import java.util.Collection; + +import org.springframework.core.CollectionFactory; +import org.springframework.core.convert.TypeDescriptor; + +class CollectionToCollectionGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public CollectionToCollectionGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + Collection sourceCollection = (Collection) source; + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + if (sourceElementType == TypeDescriptor.NULL) { + sourceElementType = getElementType(sourceCollection); + } + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + if (sourceElementType == TypeDescriptor.NULL || sourceElementType.isAssignableTo(targetElementType)) { + if (sourceType.isAssignableTo(targetType)) { + return sourceCollection; + } else { + Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); + targetCollection.addAll(sourceCollection); + return targetCollection; + } + } + Collection targetCollection = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); + GenericConverter converter = conversionService.getConverter(sourceElementType, targetElementType); + for (Object element : sourceCollection) { + targetCollection.add(converter.convert(element, sourceElementType, targetElementType)); + } + return targetCollection; + } + + private TypeDescriptor getElementType(Collection collection) { + for (Object element : collection) { + if (element != null) { + return TypeDescriptor.valueOf(element.getClass()); + } + } + return TypeDescriptor.NULL; + } + +} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectGenericConverter.java new file mode 100644 index 00000000000..071434972bc --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectGenericConverter.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import org.springframework.core.convert.TypeDescriptor; + +class CollectionToObjectGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public CollectionToObjectGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +} 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 8ccffca8d0f..1d82ee0920a 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 @@ -16,13 +16,14 @@ package org.springframework.core.convert.support; +import java.lang.reflect.Array; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -38,6 +39,7 @@ import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.ConverterInfo; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * Base implementation of a conversion service. @@ -55,8 +57,6 @@ public class GenericConversionService implements ConversionService, ConverterReg private final Map> sourceTypeConverters = new HashMap>(); - private final Set matchableConverters = new LinkedHashSet(); - public GenericConversionService() { initGenericConverters(); } @@ -182,24 +182,23 @@ public class GenericConversionService implements ConversionService, ConverterReg // subclassing hooks protected void initGenericConverters() { - addGenericConverter(new CollectionGenericConverter(this)); - addGenericConverter(new MapGenericConverter(this)); + addGenericConverter(Object[].class, Object[].class, new ArrayToArrayGenericConverter(this)); + addGenericConverter(Object[].class, Collection.class, new ArrayToCollectionGenericConverter(this)); + addGenericConverter(Object[].class, Object.class, new ArrayToObjectGenericConverter(this)); + addGenericConverter(Collection.class, Collection.class, new CollectionToCollectionGenericConverter(this)); + addGenericConverter(Collection.class, Object[].class, new CollectionToArrayGenericConverter(this)); + addGenericConverter(Collection.class, Object.class, new CollectionToObjectGenericConverter(this)); + addGenericConverter(Map.class, Map.class, new MapToMapGenericConverter(this)); + addGenericConverter(Object.class, Object[].class, new ObjectToArrayGenericConverter(this)); + addGenericConverter(Object.class, Collection.class, new ObjectToCollectionGenericConverter(this)); } - protected void addGenericConverter(GenericConverter converter) { - this.matchableConverters.add(converter); + protected void addGenericConverter(Class sourceType, Class targetType, GenericConverter converter) { + getSourceMap(sourceType).put(targetType, converter); } protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { - GenericConverter converter = matchConverterByClassPair(sourceType.getObjectType(), targetType.getObjectType()); - if (converter == null) { - for (GenericConverter matchableConverter : this.matchableConverters) { - if (matchableConverter.canConvert(sourceType, targetType)) { - return matchableConverter; - } - } - } - return converter; + return findConverterByClassPair(sourceType.getObjectType(), targetType.getObjectType()); } // internal helpers @@ -255,7 +254,7 @@ public class GenericConversionService implements ConversionService, ConverterReg return null; } - private GenericConverter matchConverterByClassPair(Class sourceType, Class targetType) { + private GenericConverter findConverterByClassPair(Class sourceType, Class targetType) { if (sourceType.isInterface()) { LinkedList classQueue = new LinkedList(); classQueue.addFirst(sourceType); @@ -283,8 +282,15 @@ public class GenericConversionService implements ConversionService, ConverterReg if (converter != null) { return converter; } - if (currentClass.getSuperclass() != null) { - classQueue.addFirst(currentClass.getSuperclass()); + if (currentClass.isArray()) { + Class componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType()); + if (componentType.getSuperclass() != null) { + classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); + } + } else { + if (currentClass.getSuperclass() != null) { + classQueue.addFirst(currentClass.getSuperclass()); + } } Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { @@ -337,8 +343,15 @@ public class GenericConversionService implements ConversionService, ConverterReg if (converter != null) { return converter; } - if (currentClass.getSuperclass() != null) { - classQueue.addFirst(currentClass.getSuperclass()); + if (currentClass.isArray()) { + Class componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType()); + if (componentType.getSuperclass() != null) { + classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); + } + } else { + if (currentClass.getSuperclass() != null) { + classQueue.addFirst(currentClass.getSuperclass()); + } } Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { @@ -357,10 +370,6 @@ public class GenericConversionService implements ConversionService, ConverterReg this.converter = converter; } - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Should not be called"); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return converter.convert(source); } @@ -375,10 +384,6 @@ public class GenericConversionService implements ConversionService, ConverterReg this.converterFactory = converterFactory; } - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - throw new UnsupportedOperationException("Should not be called"); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return converterFactory.getConverter(targetType.getObjectType()).convert(source); } 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/support/GenericConverter.java index d21c875a1ba..050ca426c53 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/support/GenericConverter.java @@ -31,14 +31,6 @@ import org.springframework.core.convert.converter.ConverterFactory; */ public interface GenericConverter { - /** - * Can this converter convert the sourceType to targetType. - * @param sourceType context about the sourceType to convert to - * @param targetType context about the targetType to convert to - * @return true if so, false otherwise - */ - boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); - /** * Convert the source to the targetType described by the TypeDescriptor. * @param source the source object to convert (never null) diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapGenericConverter.java similarity index 94% rename from org.springframework.core/src/main/java/org/springframework/core/convert/support/MapGenericConverter.java rename to org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapGenericConverter.java index d72d22c3b57..7679e2a9a43 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapGenericConverter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapGenericConverter.java @@ -5,18 +5,14 @@ import java.util.Map; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.TypeDescriptor; -class MapGenericConverter implements GenericConverter { +class MapToMapGenericConverter implements GenericConverter { private GenericConversionService conversionService; - public MapGenericConverter(GenericConversionService conversionService) { + public MapToMapGenericConverter(GenericConversionService conversionService) { this.conversionService = conversionService; } - public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { - return sourceType.isMap() && targetType.isMap(); - } - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Map sourceMap = (Map) source; TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor(); diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayGenericConverter.java new file mode 100644 index 00000000000..13791a93939 --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayGenericConverter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import java.lang.reflect.Array; + +import org.springframework.core.convert.TypeDescriptor; + +class ObjectToArrayGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public ObjectToArrayGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + Object array = Array.newInstance(targetType.getElementType(), 1); + if (sourceType.isAssignableTo(targetElementType)) { + Array.set(array, 0, source); + } else { + GenericConverter converter = conversionService.getConverter(sourceType, targetElementType); + Array.set(array, 0, converter.convert(source, sourceType, targetElementType)); + } + return array; + } + +} \ No newline at end of file diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionGenericConverter.java b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionGenericConverter.java new file mode 100644 index 00000000000..ffd6b1cfe5d --- /dev/null +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionGenericConverter.java @@ -0,0 +1,32 @@ +/* + * Copyright 2002-2009 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.core.convert.support; + +import org.springframework.core.convert.TypeDescriptor; + +class ObjectToCollectionGenericConverter implements GenericConverter { + + private GenericConversionService conversionService; + + public ObjectToCollectionGenericConverter(GenericConversionService conversionService) { + this.conversionService = conversionService; + } + + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + throw new UnsupportedOperationException("Not yet implemented"); + } + +}