revised findCommonElement handling within TypeDescriptor.forObject(Object); we now fully introspect the collection elements to resolve the common type. We also support nested introspection e.g. collections of collections. Object.class is used to indicate no common type, and TypeDescriptor.NULL is used to indicate a null element value

This commit is contained in:
Keith Donald
2011-05-23 05:21:02 +00:00
parent 79f9d1cfc6
commit 5c67dbf424
10 changed files with 231 additions and 50 deletions

View File

@@ -0,0 +1,140 @@
package org.springframework.core.convert.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class CollectionToCollectionConverterTests {
private GenericConversionService conversionService = new GenericConversionService();
@Before
public void setUp() {
conversionService.addConverter(new CollectionToCollectionConverter(conversionService));
}
@Test
public void differentImpls() throws Exception {
List<Resource> resources = new ArrayList<Resource>();
resources.add(new ClassPathResource("test"));
resources.add(new FileSystemResource("test"));
resources.add(new TestResource());
TypeDescriptor sourceType = TypeDescriptor.forObject(resources);
assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
}
@Test
public void mixedInNulls() throws Exception {
List<Resource> resources = new ArrayList<Resource>();
resources.add(new ClassPathResource("test"));
resources.add(null);
resources.add(new FileSystemResource("test"));
resources.add(new TestResource());
TypeDescriptor sourceType = TypeDescriptor.forObject(resources);
assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
}
@Test
public void allNulls() throws Exception {
List<Resource> resources = new ArrayList<Resource>();
resources.add(null);
resources.add(null);
TypeDescriptor sourceType = TypeDescriptor.forObject(resources);
assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
}
@Test(expected=ConverterNotFoundException.class)
public void nothingInCommon() throws Exception {
List<Object> resources = new ArrayList<Object>();
resources.add(new ClassPathResource("test"));
resources.add(3);
TypeDescriptor sourceType = TypeDescriptor.forObject(resources);
assertEquals(resources, conversionService.convert(resources, sourceType, new TypeDescriptor(getClass().getField("resources"))));
}
public List<Resource> resources;
public static abstract class BaseResource implements Resource {
public InputStream getInputStream() throws IOException {
// TODO Auto-generated method stub
return null;
}
public boolean exists() {
// TODO Auto-generated method stub
return false;
}
public boolean isReadable() {
// TODO Auto-generated method stub
return false;
}
public boolean isOpen() {
// TODO Auto-generated method stub
return false;
}
public URL getURL() throws IOException {
// TODO Auto-generated method stub
return null;
}
public URI getURI() throws IOException {
// TODO Auto-generated method stub
return null;
}
public File getFile() throws IOException {
// TODO Auto-generated method stub
return null;
}
public long contentLength() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public long lastModified() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public Resource createRelative(String relativePath) throws IOException {
// TODO Auto-generated method stub
return null;
}
public String getFilename() {
// TODO Auto-generated method stub
return null;
}
public String getDescription() {
// TODO Auto-generated method stub
return null;
}
}
public static class TestResource extends BaseResource {
}
}

View File

@@ -51,6 +51,18 @@ public class MapToMapConverterTests {
assertEquals(map, conversionService.convert(map, Map.class));
}
@Test
public void scalarMapNotGenericSource() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "9");
map.put("2", "37");
TypeDescriptor sourceType = new TypeDescriptor(getClass().getField("notGenericMapSource"));
TypeDescriptor targetType = new TypeDescriptor(getClass().getField("scalarMapTarget"));
assertFalse(conversionService.canConvert(sourceType, targetType));
}
public Map notGenericMapSource;
@Test
public void collectionMap() throws Exception {
Map<String, List<String>> map = new HashMap<String, List<String>>();
@@ -115,7 +127,7 @@ public class MapToMapConverterTests {
Map<String, String> map = new HashMap<String, String>();
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));
}

View File

@@ -13,14 +13,12 @@ public class Spr7728Tests
{
private CollectionToCollectionConverter theConverter;
private Vector<String> theSrcVector;
private TypeDescriptor theSrcType;
private TypeDescriptor theTargetType;
@Before
public void setup()
{
theSrcVector = new Vector<String>();
theSrcType = TypeDescriptor.forObject(theSrcVector);
theTargetType = TypeDescriptor.forObject(new ArrayList());
theConverter = new CollectionToCollectionConverter(new GenericConversionService());
}
@@ -30,7 +28,6 @@ public class Spr7728Tests
throws Exception
{
theSrcVector.add("Element");
testCollectionConversionToArrayList(theSrcVector);
}
@@ -43,8 +40,7 @@ public class Spr7728Tests
private void testCollectionConversionToArrayList(Collection<String> aSource)
{
Object myConverted = theConverter.convert(aSource, theSrcType, theTargetType);
Object myConverted = theConverter.convert(aSource, TypeDescriptor.forObject(aSource), theTargetType);
Assert.assertTrue(myConverted instanceof ArrayList<?>);
Assert.assertEquals(aSource.size(), ((ArrayList<?>) myConverted).size());
}