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 820b0bd855d..d1ae65fbc87 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 @@ -59,11 +59,20 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter { } int length = Array.getLength(source); Collection target = CollectionFactory.createCollection(targetType.getType(), length); - for (int i = 0; i < length; i++) { - Object sourceElement = Array.get(source, i); - Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor()); - target.add(targetElement); - } + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + if (Object.class.equals(targetElementType.getType())) { + for (int i = 0; i < length; i++) { + Object sourceElement = Array.get(source, i); + target.add(sourceElement); + } + } else { + for (int i = 0; i < length; i++) { + Object sourceElement = Array.get(source, i); + Object targetElement = this.conversionService.convert(sourceElement, sourceElementType, targetElementType); + target.add(targetElement); + } + } return target; } 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 c97da5c74ea..1a54472d37a 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 @@ -61,9 +61,17 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert } Collection sourceCollection = (Collection) source; Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); - for (Object sourceElement : sourceCollection) { - Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor()); - target.add(targetElement); + TypeDescriptor sourceElementType = sourceType.getElementTypeDescriptor(); + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + if (Object.class.equals(targetElementType.getType())) { + for (Object sourceElement : sourceCollection) { + target.add(sourceElement); + } + } else { + for (Object sourceElement : sourceCollection) { + Object targetElement = this.conversionService.convert(sourceElement, sourceElementType, targetElementType); + target.add(targetElement); + } } return target; } 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 ba1f81a1f47..44c8a0892ab 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 @@ -60,7 +60,9 @@ final class MapToMapConverter implements ConditionalGenericConverter { } Map sourceMap = (Map) source; Map targetMap = CollectionFactory.createMap(targetType.getType(), sourceMap.size()); + TypeDescriptor sourceKeyType = sourceType.getMapKeyTypeDescriptor(); TypeDescriptor targetKeyType = targetType.getMapKeyTypeDescriptor(); + TypeDescriptor sourceValueType = sourceType.getMapValueTypeDescriptor(); TypeDescriptor targetValueType = targetType.getMapValueTypeDescriptor(); if (Object.class.equals(targetKeyType.getType()) && Object.class.equals(targetValueType.getType())) { for (Map.Entry entry : sourceMap.entrySet()) { @@ -70,8 +72,8 @@ final class MapToMapConverter implements ConditionalGenericConverter { for (Map.Entry entry : sourceMap.entrySet()) { Object sourceKey = entry.getKey(); Object sourceValue = entry.getValue(); - Object targetKey = this.conversionService.convert(sourceKey, sourceType.getMapKeyTypeDescriptor(), targetType.getMapKeyTypeDescriptor()); - Object targetValue = this.conversionService.convert(sourceValue, sourceType.getMapValueTypeDescriptor(), targetType.getMapValueTypeDescriptor()); + Object targetKey = this.conversionService.convert(sourceKey, sourceKeyType, targetKeyType); + Object targetValue = this.conversionService.convert(sourceValue, sourceValueType, targetValueType); targetMap.put(targetKey, targetValue); } } 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 df70b15a94b..0f6342cd99b 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 @@ -55,13 +55,12 @@ final class ObjectToCollectionConverter implements ConditionalGenericConverter { return null; } Collection target = CollectionFactory.createCollection(targetType.getType(), 1); - TypeDescriptor elementType = targetType.getElementTypeDescriptor(); - // Avoid potential recursion... - if (!Collection.class.isAssignableFrom(elementType.getType())) { - target.add(this.conversionService.convert(source, sourceType, elementType)); - } - else { - target.add(source); + TypeDescriptor targetElementType = targetType.getElementTypeDescriptor(); + // Avoid potential recursion.... + if (targetElementType.isCollection()) { + target.add(source); + } else { + target.add(this.conversionService.convert(source, sourceType, targetElementType)); } return target; } diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java index 51260ea6616..d6eb5596d88 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/support/CollectionToCollectionConverterTests.java @@ -1,7 +1,8 @@ package org.springframework.core.convert.support; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; @@ -9,6 +10,8 @@ import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; import java.util.List; import org.junit.Before; @@ -28,6 +31,114 @@ public class CollectionToCollectionConverterTests { conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); } + @Test + public void scalarList() throws Exception { + List list = new ArrayList(); + list.add("9"); + list.add("37"); + TypeDescriptor sourceType = TypeDescriptor.forObject(list); + TypeDescriptor targetType = new TypeDescriptor(getClass().getField("scalarListTarget")); + assertFalse(conversionService.canConvert(sourceType, targetType)); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + assertTrue(conversionService.canConvert(sourceType, targetType)); + @SuppressWarnings("unchecked") + List result = (List) conversionService.convert(list, sourceType, targetType); + assertFalse(list.equals(result)); + assertEquals((Integer) 9, result.get(0)); + assertEquals((Integer) 37, result.get(1)); + } + + public List scalarListTarget; + + @Test + public void emptyListToList() throws Exception { + conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + List list = new ArrayList(); + TypeDescriptor sourceType = TypeDescriptor.forObject(list); + TypeDescriptor targetType = new TypeDescriptor(getClass().getField("emptyListTarget")); + assertTrue(conversionService.canConvert(sourceType, targetType)); + assertEquals(list, conversionService.convert(list, sourceType, targetType)); + } + + public List emptyListTarget; + + @Test + public void emptyListToListDifferentTargetType() throws Exception { + conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + List list = new ArrayList(); + TypeDescriptor sourceType = TypeDescriptor.forObject(list); + TypeDescriptor targetType = new TypeDescriptor(getClass().getField("emptyListDifferentTarget")); + assertTrue(conversionService.canConvert(sourceType, targetType)); + @SuppressWarnings("unchecked") + LinkedList result = (LinkedList) conversionService.convert(list, sourceType, targetType); + assertEquals(LinkedList.class, result.getClass()); + assertTrue(result.isEmpty()); + } + + public LinkedList emptyListDifferentTarget; + + @Test + public void collectionToObjectInteraction() throws Exception { + List> list = new ArrayList>(); + list.add(Arrays.asList("9", "12")); + list.add(Arrays.asList("37", "23")); + conversionService.addConverter(new CollectionToObjectConverter(conversionService)); + assertTrue(conversionService.canConvert(List.class, List.class)); + assertEquals(list, conversionService.convert(list, List.class)); + } + + @Test + public void arrayCollectionToObjectInteraction() throws Exception { + List[] array = new List[2]; + array[0] = Arrays.asList("9", "12"); + array[1] = Arrays.asList("37", "23"); + conversionService.addConverter(new ArrayToCollectionConverter(conversionService)); + conversionService.addConverter(new CollectionToObjectConverter(conversionService)); + assertTrue(conversionService.canConvert(String[].class, List.class)); + assertEquals(Arrays.asList(array), conversionService.convert(array, List.class)); + } + + @Test + public void objectToCollection() throws Exception { + List> list = new ArrayList>(); + list.add(Arrays.asList("9", "12")); + list.add(Arrays.asList("37", "23")); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + conversionService.addConverter(new ObjectToCollectionConverter(conversionService)); + conversionService.addConverter(new CollectionToObjectConverter(conversionService)); + TypeDescriptor sourceType = TypeDescriptor.forObject(list); + TypeDescriptor targetType = new TypeDescriptor(getClass().getField("objectToCollection")); + assertTrue(conversionService.canConvert(sourceType, targetType)); + List>> result = (List>>) conversionService.convert(list, sourceType, targetType); + assertEquals((Integer)9, result.get(0).get(0).get(0)); + assertEquals((Integer)12, result.get(0).get(1).get(0)); + assertEquals((Integer)37, result.get(1).get(0).get(0)); + assertEquals((Integer)23, result.get(1).get(1).get(0)); + } + + public List>> objectToCollection; + + @Test + public void stringToCollection() throws Exception { + List> list = new ArrayList>(); + list.add(Arrays.asList("9,12")); + list.add(Arrays.asList("37,23")); + conversionService.addConverterFactory(new StringToNumberConverterFactory()); + conversionService.addConverter(new StringToCollectionConverter(conversionService)); + conversionService.addConverter(new ObjectToCollectionConverter(conversionService)); + conversionService.addConverter(new CollectionToObjectConverter(conversionService)); + TypeDescriptor sourceType = TypeDescriptor.forObject(list); + TypeDescriptor targetType = new TypeDescriptor(getClass().getField("objectToCollection")); + assertTrue(conversionService.canConvert(sourceType, targetType)); + List>> result = (List>>) conversionService.convert(list, sourceType, targetType); + assertEquals((Integer)9, result.get(0).get(0).get(0)); + assertEquals((Integer)12, result.get(0).get(0).get(1)); + assertEquals((Integer)37, result.get(1).get(0).get(0)); + assertEquals((Integer)23, result.get(1).get(0).get(1)); + } + @Test public void differentImpls() throws Exception { List resources = new ArrayList(); @@ -69,7 +180,7 @@ public class CollectionToCollectionConverterTests { public List resources; - public static abstract class BaseResource implements Resource { + public static abstract class BaseResource implements Resource { public InputStream getInputStream() throws IOException { // TODO Auto-generated method stub 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 d7b8e3689d9..8a98ef6d504 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 @@ -16,7 +16,16 @@ package org.springframework.core.convert.support; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -24,9 +33,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import static org.junit.Assert.*; import org.junit.Test; - import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; @@ -261,8 +268,13 @@ public class GenericConversionServiceTests { @Test public void testListOfList() { GenericConversionService service = new DefaultConversionService(); - List> list = Collections.singletonList(Collections.singletonList("Foo")); - assertNotNull(service.convert(list, String.class)); + List list1 = Arrays.asList("Foo", "Bar"); + List list2 = Arrays.asList("Baz", "Boop"); + @SuppressWarnings("unchecked") + List> list = Arrays.asList(list1, list2); + String result = service.convert(list, String.class); + assertNotNull(result); + assertEquals("Foo,Bar,Baz,Boop", result); } @Test @@ -360,36 +372,6 @@ public class GenericConversionServiceTests { public static Map map; - - @Test - public void emptyListToList() throws Exception { - conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); - conversionService.addConverterFactory(new StringToNumberConverterFactory()); - List list = new ArrayList(); - TypeDescriptor sourceType = TypeDescriptor.forObject(list); - TypeDescriptor targetType = new TypeDescriptor(getClass().getField("emptyListTarget")); - assertTrue(conversionService.canConvert(sourceType, targetType)); - assertEquals(list, conversionService.convert(list, sourceType, targetType)); - } - - public List emptyListTarget; - - @Test - public void emptyListToListDifferentTargetType() throws Exception { - conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); - conversionService.addConverterFactory(new StringToNumberConverterFactory()); - List list = new ArrayList(); - TypeDescriptor sourceType = TypeDescriptor.forObject(list); - TypeDescriptor targetType = new TypeDescriptor(getClass().getField("emptyListDifferentTarget")); - assertTrue(conversionService.canConvert(sourceType, targetType)); - @SuppressWarnings("unchecked") - LinkedList result = (LinkedList) conversionService.convert(list, sourceType, targetType); - assertEquals(LinkedList.class, result.getClass()); - assertTrue(result.isEmpty()); - } - - public LinkedList emptyListDifferentTarget; - @Test public void emptyListToArray() throws Exception { conversionService.addConverter(new CollectionToArrayConverter(conversionService)); diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/support/MapToMapConverterTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/support/MapToMapConverterTests.java index d70e7d4ea6d..7e8f7086380 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/support/MapToMapConverterTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/support/MapToMapConverterTests.java @@ -52,7 +52,7 @@ public class MapToMapConverterTests { } @Test - public void scalarMapNotGenericSource() throws Exception { + public void scalarMapNotGenericSourceField() throws Exception { Map map = new HashMap(); map.put("1", "9"); map.put("2", "37"); @@ -117,6 +117,7 @@ public class MapToMapConverterTests { Map> map = new HashMap>(); map.put("1", Arrays.asList("9", "12")); map.put("2", Arrays.asList("37", "23")); + conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverter(new CollectionToObjectConverter(conversionService)); assertTrue(conversionService.canConvert(Map.class, Map.class)); assertEquals(map, conversionService.convert(map, Map.class)); @@ -127,7 +128,7 @@ public class MapToMapConverterTests { Map map = new HashMap(); TypeDescriptor sourceType = TypeDescriptor.forObject(map); TypeDescriptor targetType = new TypeDescriptor(getClass().getField("emptyMapTarget")); - //assertTrue(conversionService.canConvert(sourceType, targetType)); + assertTrue(conversionService.canConvert(sourceType, targetType)); assertEquals(map, conversionService.convert(map, sourceType, targetType)); } diff --git a/org.springframework.core/src/test/resources/log4j.xml b/org.springframework.core/src/test/resources/log4j.xml index 576b4395d78..bd37e274728 100644 --- a/org.springframework.core/src/test/resources/log4j.xml +++ b/org.springframework.core/src/test/resources/log4j.xml @@ -11,7 +11,7 @@ - +