From a8dbac6d8d8e185f032476e2260fea797e146d39 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Fri, 3 Jun 2011 01:55:41 +0000 Subject: [PATCH] more tests --- .../core/convert/TypeDescriptorTests.java | 917 ++++++++++-------- 1 file changed, 515 insertions(+), 402 deletions(-) diff --git a/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java b/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java index 6b00df5785..9592450d67 100644 --- a/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java +++ b/org.springframework.core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java @@ -22,32 +22,25 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import org.apache.commons.logging.LogFactory; import org.junit.Ignore; import org.junit.Test; -import org.springframework.core.BridgeMethodResolver; -import org.springframework.core.GenericTypeResolver; import org.springframework.core.MethodParameter; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; /** + * @author Keith Donald * @author Andy Clement */ public class TypeDescriptorTests { @@ -69,111 +62,337 @@ public class TypeDescriptorTests { public Map> nestedMapField = new HashMap>(); @Test - public void forCollection() { - List list = new ArrayList(); - list.add("1"); - TypeDescriptor desc = TypeDescriptor.forObject(list); - assertEquals(String.class, desc.getElementType()); + public void parameterPrimitive() throws Exception { + TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterPrimitive", int.class), 0)); + assertEquals(int.class, desc.getType()); + assertEquals(Integer.class, desc.getObjectType()); + assertEquals("int", desc.getName()); + assertEquals("int", desc.toString()); + assertTrue(desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(!desc.isCollection()); + assertNull(desc.getElementType()); + assertEquals(TypeDescriptor.NULL, desc.getElementTypeDescriptor()); + assertTrue(!desc.isMap()); + assertNull(desc.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, desc.getMapKeyTypeDescriptor()); + assertNull(desc.getMapValueType()); + assertEquals(TypeDescriptor.NULL, desc.getMapValueTypeDescriptor()); } - + + public void testParameterPrimitive(int primitive) { + + } + @Test - public void forCollectionEmpty() { - List list = new ArrayList(); - TypeDescriptor desc = TypeDescriptor.forObject(list); + public void parameterScalar() throws Exception { + TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterScalar", String.class), 0)); + assertEquals(String.class, desc.getType()); + assertEquals(String.class, desc.getObjectType()); + assertEquals("java.lang.String", desc.getName()); + assertEquals("java.lang.String", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); assertNull(desc.getElementType()); + assertEquals(TypeDescriptor.NULL, desc.getElementTypeDescriptor()); + assertFalse(desc.isMap()); + assertNull(desc.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, desc.getMapKeyTypeDescriptor()); + assertNull(desc.getMapValueType()); + assertEquals(TypeDescriptor.NULL, desc.getMapValueTypeDescriptor()); + } + + public void testParameterScalar(String value) { + } @Test - public void forCollectionSuperClassCommonType() throws SecurityException, NoSuchFieldException { - List list = new ArrayList(); - list.add(1); - list.add(2L); - TypeDescriptor desc = TypeDescriptor.forObject(list); - assertEquals(Number.class, desc.getElementType()); + public void parameterList() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterList", List.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List>>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertEquals(List.class, desc.getElementType()); + assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getElementTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getElementTypeDescriptor().getElementTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 3), desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor()); + assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapKeyTypeDescriptor().getType()); + assertEquals(Enum.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor().getType()); + assertFalse(desc.isMap()); + assertNull(desc.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, desc.getMapKeyTypeDescriptor()); + assertNull(desc.getMapValueType()); + assertEquals(TypeDescriptor.NULL, desc.getMapValueTypeDescriptor()); } - public List longs; + public void testParameterList(List>>> list) { + + } + + @Test + public void parameterListNoParamTypes() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterListNoParamTypes", List.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(List.class, desc.getType()); + assertEquals(List.class, desc.getObjectType()); + assertEquals("java.util.List", desc.getName()); + assertEquals("java.util.List", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertTrue(desc.isCollection()); + assertFalse(desc.isArray()); + assertEquals(Object.class, desc.getElementType()); + assertEquals(TypeDescriptor.valueOf(Object.class), desc.getElementTypeDescriptor()); + assertFalse(desc.isMap()); + assertNull(desc.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, desc.getMapKeyTypeDescriptor()); + assertNull(desc.getMapValueType()); + assertEquals(TypeDescriptor.NULL, desc.getMapValueTypeDescriptor()); + } + + public void testParameterListNoParamTypes(List list) { + + } + + @Test + public void parameterArray() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterArray", Integer[].class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(Integer[].class, desc.getType()); + assertEquals(Integer[].class, desc.getObjectType()); + assertEquals("java.lang.Integer[]", desc.getName()); + assertEquals("java.lang.Integer[]", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertTrue(desc.isArray()); + assertEquals(Integer.class, desc.getElementType()); + assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor()); + assertTrue(!desc.isMap()); + assertNull(desc.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, desc.getMapKeyTypeDescriptor()); + assertNull(desc.getMapValueType()); + assertEquals(TypeDescriptor.NULL, desc.getMapValueTypeDescriptor()); + } + + public void testParameterArray(Integer[] array) { + + } @Test - public void forCollectionNoObviousCommonType() { - List collection = new ArrayList(); - List list = new ArrayList(); - list.add("1"); - collection.add(list); - Map map = new HashMap(); - collection.add(map); - map.put("1", "2"); - TypeDescriptor desc = TypeDescriptor.forObject(collection); - assertEquals(Cloneable.class, desc.getElementType()); + public void parameterMap() throws Exception { + MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterMap", Map.class), 0); + TypeDescriptor desc = new TypeDescriptor(methodParameter); + assertEquals(Map.class, desc.getType()); + assertEquals(Map.class, desc.getObjectType()); + assertEquals("java.util.Map", desc.getName()); + assertEquals("java.util.Map>", desc.toString()); + assertTrue(!desc.isPrimitive()); + assertEquals(0, desc.getAnnotations().length); + assertFalse(desc.isCollection()); + assertFalse(desc.isArray()); + assertNull(desc.getElementType()); + assertEquals(TypeDescriptor.NULL, desc.getElementTypeDescriptor()); + assertTrue(desc.isMap()); + assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getMapValueTypeDescriptor()); + assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getMapValueTypeDescriptor().getElementTypeDescriptor()); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getType()); + assertEquals(List.class, desc.getMapValueTypeDescriptor().getType()); + assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType()); + } + + public void testParameterMap(Map> map) { + } @Test - public void forCollectionNoCommonType() { - List collection = new ArrayList(); - collection.add(new Object()); - collection.add("1"); - TypeDescriptor desc = TypeDescriptor.forObject(collection); - assertEquals(Object.class, desc.getElementType()); + public void parameterAnnotated() throws Exception { + TypeDescriptor t1 = new TypeDescriptor(new MethodParameter(getClass().getMethod("testAnnotatedMethod", String.class), 0)); + assertEquals(String.class, t1.getType()); + assertEquals(1, t1.getAnnotations().length); + assertNotNull(t1.getAnnotation(ParameterAnnotation.class)); + } + + @Target({ElementType.PARAMETER}) + @Retention(RetentionPolicy.RUNTIME) + public @interface ParameterAnnotation { + + } + + public void testAnnotatedMethod(@ParameterAnnotation String parameter) { + } @Test - public void forCollectionNested() { - List collection = new ArrayList(); - collection.add(Arrays.asList("1", "2")); - collection.add(Arrays.asList("3", "4")); - TypeDescriptor desc = TypeDescriptor.forObject(collection); - assertEquals(Arrays.asList("foo").getClass(), desc.getElementType()); - assertEquals(String.class, desc.getElementTypeDescriptor().getElementType()); + public void propertyComplex() throws Exception { + PropertyDescriptor property = new PropertyDescriptor("complexProperty", getClass().getMethod("getComplexProperty", null), getClass().getMethod("setComplexProperty", Map.class)); + TypeDescriptor desc = new TypeDescriptor(getClass(), property); + //assertEquals(String.class, desc.getMapKeyType()); + assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementType()); + } + + public Map>> getComplexProperty() { + return null; + } + + public void setComplexProperty(Map>> complexProperty) { + } @Test - public void forMap() { - Map map = new HashMap(); - map.put("1", "2"); - TypeDescriptor desc = TypeDescriptor.forObject(map); - assertEquals(String.class, desc.getMapKeyType()); - assertEquals(String.class, desc.getMapValueType()); + public void propertyGenericType() throws Exception { + GenericType genericBean = new IntegerType(); + PropertyDescriptor property = new PropertyDescriptor("property", genericBean.getClass().getMethod("getProperty", null), genericBean.getClass().getMethod("setProperty", Integer.class)); + TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); + assertEquals(Integer.class, desc.getType()); } @Test - public void forMapEmpty() { - Map map = new HashMap(); - TypeDescriptor desc = TypeDescriptor.forObject(map); - assertNull(desc.getMapKeyType()); - assertNull(desc.getMapValueType()); + public void propertyGenericTypeList() throws Exception { + GenericType genericBean = new IntegerType(); + PropertyDescriptor property = new PropertyDescriptor("listProperty", genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class)); + TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); + assertEquals(List.class, desc.getType()); + assertEquals(Integer.class, desc.getElementType()); + } + + public interface GenericType { + T getProperty(); + + void setProperty(T t); + + List getListProperty(); + + void setListProperty(List t); + + } + + public class IntegerType implements GenericType { + + public Integer getProperty() { + // TODO Auto-generated method stub + return null; + } + + public void setProperty(Integer t) { + // TODO Auto-generated method stub + + } + + public List getListProperty() { + // TODO Auto-generated method stub + return null; + } + + public void setListProperty(List t) { + // TODO Auto-generated method stub + + } + } @Test - public void forMapCommonSuperClass() { - Map map = new HashMap(); - map.put(1, 2); - map.put(2L, 3L); - TypeDescriptor desc = TypeDescriptor.forObject(map); - assertEquals(Number.class, desc.getMapKeyType()); - assertEquals(Number.class, desc.getMapValueType()); + public void propertyGenericClassList() throws Exception { + IntegerClass genericBean = new IntegerClass(); + PropertyDescriptor property = new PropertyDescriptor("listProperty", genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class)); + TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); + assertEquals(List.class, desc.getType()); + assertEquals(Integer.class, desc.getElementType()); + } + + public static class GenericClass { + + public T getProperty() { + return null; + } + + public void setProperty(T t) { + } + + public List getListProperty() { + return null; + } + + public void setListProperty(List t) { + } + + } + + public static class IntegerClass extends GenericClass { + } @Test - public void forMapNoObviousCommonType() { - Map map = new HashMap(); - map.put("1", "2"); - map.put(2, 2); - TypeDescriptor desc = TypeDescriptor.forObject(map); - assertEquals(Comparable.class, desc.getMapKeyType()); - assertEquals(Comparable.class, desc.getMapValueType()); + public void property() throws Exception { + PropertyDescriptor property = new PropertyDescriptor("property", getClass().getMethod("getProperty", null), getClass().getMethod("setProperty", Map.class)); + TypeDescriptor desc = new TypeDescriptor(getClass(), property); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementType()); + assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementType()); + assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); + assertNotNull(desc.getAnnotation(MethodAnnotation2.class)); + assertNotNull(desc.getAnnotation(MethodAnnotation3.class)); + } + + @MethodAnnotation1 + public Map, List> getProperty() { + return property; + } + + @MethodAnnotation2 + public void setProperty(Map, List> property) { + this.property = property; + } + + @MethodAnnotation3 + private Map, List> property; + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation1 { + + } + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation2 { + + } + + @Target({ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MethodAnnotation3 { + } @Test - public void forMapNested() { - Map> map = new HashMap>(); - map.put(1, Arrays.asList("1, 2")); - TypeDescriptor desc = TypeDescriptor.forObject(map); - assertEquals(Integer.class, desc.getMapKeyType()); - assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementType()); + public void fieldScalar() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldScalar")); + assertFalse(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.class, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + assertNull(typeDescriptor.getElementType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getElementTypeDescriptor()); + assertNull(typeDescriptor.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapKeyTypeDescriptor()); + assertNull(typeDescriptor.getMapValueType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapValueTypeDescriptor()); } + public Integer fieldScalar; + @Test - public void listDescriptor() throws Exception { + public void fieldList() throws Exception { TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString")); assertFalse(typeDescriptor.isArray()); assertEquals(List.class, typeDescriptor.getType()); @@ -183,7 +402,7 @@ public class TypeDescriptorTests { } @Test - public void listOfListOfStringDescriptor() throws Exception { + public void fieldListOfListOfString() throws Exception { TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfString")); assertFalse(typeDescriptor.isArray()); assertEquals(List.class, typeDescriptor.getType()); @@ -193,7 +412,7 @@ public class TypeDescriptorTests { } @Test - public void listOfListOfUnknownDescriptor() throws Exception { + public void fieldListOfListUnknown() throws Exception { TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfUnknown")); assertFalse(typeDescriptor.isArray()); assertEquals(List.class, typeDescriptor.getType()); @@ -203,7 +422,7 @@ public class TypeDescriptorTests { } @Test - public void arrayTypeDescriptor() throws Exception { + public void fieldArray() throws Exception { TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("intArray")); assertTrue(typeDescriptor.isArray()); assertEquals(Integer.TYPE,typeDescriptor.getElementType()); @@ -211,73 +430,217 @@ public class TypeDescriptorTests { } @Test - public void buildingArrayTypeDescriptor() throws Exception { + @Ignore + public void fieldComplexTypeDescriptor() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("arrayOfListOfString")); + assertTrue(typeDescriptor.isArray()); + assertEquals(List.class,typeDescriptor.getElementType()); + assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementType()); + assertEquals("java.util.List[]",typeDescriptor.toString()); + } + + @Test + public void fieldComplexTypeDescriptor2() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField")); + assertTrue(typeDescriptor.isMap()); + assertEquals(String.class,typeDescriptor.getMapKeyType()); + assertEquals(List.class, typeDescriptor.getMapValueType()); + assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementType()); + assertEquals("java.util.Map>", typeDescriptor.toString()); + } + + @Test + @Ignore + public void fieldMap() throws Exception { + // TODO: SPR-8394: typeIndex handling not currently supported by fields + TypeDescriptor desc = new TypeDescriptor(getClass().getField("fieldMap")); + assertTrue(desc.isMap()); + assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementType()); + assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementType()); + } + + public Map, List> fieldMap; + + @Test + public void fieldAnnotated() throws Exception { + TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldAnnotated")); + assertEquals(1, typeDescriptor.getAnnotations().length); + assertNotNull(typeDescriptor.getAnnotation(FieldAnnotation.class)); + } + + @FieldAnnotation + public List fieldAnnotated; + + @Target({ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface FieldAnnotation { + + } + + @Test + public void valueOfScalar() { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Integer.class); + assertFalse(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.class, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + assertNull(typeDescriptor.getElementType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getElementTypeDescriptor()); + assertNull(typeDescriptor.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapKeyTypeDescriptor()); + assertNull(typeDescriptor.getMapValueType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapValueTypeDescriptor()); + } + + @Test + public void valueOfPrimitive() { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int.class); + assertTrue(typeDescriptor.isPrimitive()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Integer.TYPE, typeDescriptor.getType()); + assertEquals(Integer.class, typeDescriptor.getObjectType()); + assertNull(typeDescriptor.getElementType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getElementTypeDescriptor()); + assertNull(typeDescriptor.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapKeyTypeDescriptor()); + assertNull(typeDescriptor.getMapValueType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapValueTypeDescriptor()); + } + + @Test + public void valueOfArray() throws Exception { TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int[].class); assertTrue(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isMap()); assertEquals(Integer.TYPE, typeDescriptor.getElementType()); + assertNull(typeDescriptor.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapKeyTypeDescriptor()); + assertNull(typeDescriptor.getMapValueType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapValueTypeDescriptor()); + } + + @Test + public void valueOfCollection() throws Exception { + TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Collection.class); + assertTrue(typeDescriptor.isCollection()); + assertFalse(typeDescriptor.isArray()); + assertFalse(typeDescriptor.isMap()); + assertEquals(Object.class, typeDescriptor.getElementType()); + assertNull(typeDescriptor.getMapKeyType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapKeyTypeDescriptor()); + assertNull(typeDescriptor.getMapValueType()); + assertEquals(TypeDescriptor.NULL, typeDescriptor.getMapValueTypeDescriptor()); + } + + @Test + public void forObjectCollection() { + List list = new ArrayList(); + list.add("1"); + TypeDescriptor desc = TypeDescriptor.forObject(list); + assertEquals(String.class, desc.getElementType()); + } + + @Test + public void forObjectCollectionEmpty() { + List list = new ArrayList(); + TypeDescriptor desc = TypeDescriptor.forObject(list); + assertNull(desc.getElementType()); + } + + @Test + public void forObjectCollectionSuperClassCommonType() throws SecurityException, NoSuchFieldException { + List list = new ArrayList(); + list.add(1); + list.add(2L); + TypeDescriptor desc = TypeDescriptor.forObject(list); + assertEquals(Number.class, desc.getElementType()); + } + + public List longs; + + @Test + public void forObjectCollectionNoObviousCommonType() { + List collection = new ArrayList(); + List list = new ArrayList(); + list.add("1"); + collection.add(list); + Map map = new HashMap(); + collection.add(map); + map.put("1", "2"); + TypeDescriptor desc = TypeDescriptor.forObject(collection); + assertEquals(Cloneable.class, desc.getElementType()); + } + + @Test + public void forObjectCollectionNoCommonType() { + List collection = new ArrayList(); + collection.add(new Object()); + collection.add("1"); + TypeDescriptor desc = TypeDescriptor.forObject(collection); + assertEquals(Object.class, desc.getElementType()); + } + + @Test + public void forObjectCollectionNested() { + List collection = new ArrayList(); + collection.add(Arrays.asList("1", "2")); + collection.add(Arrays.asList("3", "4")); + TypeDescriptor desc = TypeDescriptor.forObject(collection); + assertEquals(Arrays.asList("foo").getClass(), desc.getElementType()); + assertEquals(String.class, desc.getElementTypeDescriptor().getElementType()); } @Test - @Ignore - public void complexTypeDescriptor() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("arrayOfListOfString")); - assertTrue(typeDescriptor.isArray()); - assertEquals(List.class,typeDescriptor.getElementType()); - assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementType()); - assertEquals("java.util.List[]",typeDescriptor.toString()); + public void forObjectMap() { + Map map = new HashMap(); + map.put("1", "2"); + TypeDescriptor desc = TypeDescriptor.forObject(map); + assertEquals(String.class, desc.getMapKeyType()); + assertEquals(String.class, desc.getMapValueType()); } @Test - public void complexTypeDescriptor2() throws Exception { - TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField")); - assertTrue(typeDescriptor.isMap()); - assertEquals(String.class,typeDescriptor.getMapKeyType()); - assertEquals(List.class, typeDescriptor.getMapValueType()); - assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementType()); - assertEquals("java.util.Map>", typeDescriptor.toString()); + public void forObjectMapEmpty() { + Map map = new HashMap(); + TypeDescriptor desc = TypeDescriptor.forObject(map); + assertNull(desc.getMapKeyType()); + assertNull(desc.getMapValueType()); } @Test - public void testEquals() throws Exception { - TypeDescriptor t1 = TypeDescriptor.valueOf(String.class); - TypeDescriptor t2 = TypeDescriptor.valueOf(String.class); - TypeDescriptor t3 = TypeDescriptor.valueOf(Date.class); - TypeDescriptor t4 = TypeDescriptor.valueOf(Date.class); - TypeDescriptor t5 = TypeDescriptor.valueOf(List.class); - TypeDescriptor t6 = TypeDescriptor.valueOf(List.class); - TypeDescriptor t7 = TypeDescriptor.valueOf(Map.class); - TypeDescriptor t8 = TypeDescriptor.valueOf(Map.class); - assertEquals(t1, t2); - assertEquals(t3, t4); - assertEquals(t5, t6); - assertEquals(t7, t8); - - TypeDescriptor t9 = new TypeDescriptor(getClass().getField("listField")); - TypeDescriptor t10 = new TypeDescriptor(getClass().getField("listField")); - assertEquals(t9, t10); - - TypeDescriptor t11 = new TypeDescriptor(getClass().getField("mapField")); - TypeDescriptor t12 = new TypeDescriptor(getClass().getField("mapField")); - assertEquals(t11, t12); + public void forObjectMapCommonSuperClass() { + Map map = new HashMap(); + map.put(1, 2); + map.put(2L, 3L); + TypeDescriptor desc = TypeDescriptor.forObject(map); + assertEquals(Number.class, desc.getMapKeyType()); + assertEquals(Number.class, desc.getMapValueType()); } - + @Test - public void annotatedMethod() throws Exception { - TypeDescriptor t1 = new TypeDescriptor(new MethodParameter(getClass().getMethod("testAnnotatedMethod", String.class), 0)); - assertEquals(String.class, t1.getType()); - assertNotNull(t1.getAnnotation(ParameterAnnotation.class)); + public void forObjectMapNoObviousCommonType() { + Map map = new HashMap(); + map.put("1", "2"); + map.put(2, 2); + TypeDescriptor desc = TypeDescriptor.forObject(map); + assertEquals(Comparable.class, desc.getMapKeyType()); + assertEquals(Comparable.class, desc.getMapValueType()); } - @Target({ElementType.PARAMETER}) - @Retention(RetentionPolicy.RUNTIME) - public @interface ParameterAnnotation { - - } - - public void testAnnotatedMethod(@ParameterAnnotation String parameter) { - + @Test + public void forObjectMapNested() { + Map> map = new HashMap>(); + map.put(1, Arrays.asList("1, 2")); + TypeDescriptor desc = TypeDescriptor.forObject(map); + assertEquals(Integer.class, desc.getMapKeyType()); + assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementType()); } - + @Test public void nestedMethodParameterType() throws Exception { TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test1", List.class), 0), 1); @@ -354,279 +717,29 @@ public class TypeDescriptorTests { public void setTest4(List> test4) { } - - @Test - public void property() throws Exception { - PropertyDescriptor property = new PropertyDescriptor("property", getClass().getMethod("getProperty", null), getClass().getMethod("setProperty", Map.class)); - TypeDescriptor desc = new TypeDescriptor(getClass(), property); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementType()); - assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementType()); - assertNotNull(desc.getAnnotation(MethodAnnotation1.class)); - assertNotNull(desc.getAnnotation(MethodAnnotation2.class)); - assertNotNull(desc.getAnnotation(MethodAnnotation3.class)); - } - - @MethodAnnotation1 - public Map, List> getProperty() { - return property; - } - - @MethodAnnotation2 - public void setProperty(Map, List> property) { - this.property = property; - } - - @MethodAnnotation3 - private Map, List> property; - - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation1 { - - } - - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation2 { - - } - - @Target({ElementType.FIELD}) - @Retention(RetentionPolicy.RUNTIME) - public @interface MethodAnnotation3 { - - } - - @Test - @Ignore - public void field() throws Exception { - // typeIndex handling not currently supported by fields - TypeDescriptor desc = new TypeDescriptor(getClass().getField("field")); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementType()); - assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementType()); - } - - public Map, List> field; - - - @Test - public void methodParameter() throws Exception { - TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("setProperty", Map.class), 0)); - assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementType()); - assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementType()); - } - - @Test - public void complexProperty() throws Exception { - PropertyDescriptor property = new PropertyDescriptor("complexProperty", getClass().getMethod("getComplexProperty", null), getClass().getMethod("setComplexProperty", Map.class)); - TypeDescriptor desc = new TypeDescriptor(getClass(), property); - //assertEquals(String.class, desc.getMapKeyType()); - assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementType()); - } - - public Map>> getComplexProperty() { - return null; - } - - public void setComplexProperty(Map>> complexProperty) { - - } - - @Test - public void genericType() throws Exception { - GenericType genericBean = new IntegerType(); - PropertyDescriptor property = new PropertyDescriptor("property", genericBean.getClass().getMethod("getProperty", null), genericBean.getClass().getMethod("setProperty", Integer.class)); - TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); - assertEquals(Integer.class, desc.getType()); - } - - @Test - public void genericTypeList() throws Exception { - GenericType genericBean = new IntegerType(); - PropertyDescriptor property = new PropertyDescriptor("listProperty", genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class)); - TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); - assertEquals(List.class, desc.getType()); - assertEquals(Integer.class, desc.getElementType()); - } - - public interface GenericType { - T getProperty(); - - void setProperty(T t); - - List getListProperty(); - - void setListProperty(List t); - - } - - public class IntegerType implements GenericType { - - public Integer getProperty() { - // TODO Auto-generated method stub - return null; - } - - public void setProperty(Integer t) { - // TODO Auto-generated method stub - - } - - public List getListProperty() { - // TODO Auto-generated method stub - return null; - } - - public void setListProperty(List t) { - // TODO Auto-generated method stub - - } - - } @Test - public void genericClassList() throws Exception { - IntegerClass genericBean = new IntegerClass(); - PropertyDescriptor property = new GenericTypeAwarePropertyDescriptor(genericBean.getClass(), "listProperty", genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class), null); - TypeDescriptor desc = new TypeDescriptor(genericBean.getClass(), property); - assertEquals(List.class, desc.getType()); - assertEquals(Integer.class, desc.getElementType()); - } - - public static class GenericClass { - - public T getProperty() { - return null; - } - - public void setProperty(T t) { - } - - public List getListProperty() { - return null; - } - - public void setListProperty(List t) { - } - - } - - public static class IntegerClass extends GenericClass { + public void testEquals() throws Exception { + TypeDescriptor t1 = TypeDescriptor.valueOf(String.class); + TypeDescriptor t2 = TypeDescriptor.valueOf(String.class); + TypeDescriptor t3 = TypeDescriptor.valueOf(Date.class); + TypeDescriptor t4 = TypeDescriptor.valueOf(Date.class); + TypeDescriptor t5 = TypeDescriptor.valueOf(List.class); + TypeDescriptor t6 = TypeDescriptor.valueOf(List.class); + TypeDescriptor t7 = TypeDescriptor.valueOf(Map.class); + TypeDescriptor t8 = TypeDescriptor.valueOf(Map.class); + assertEquals(t1, t2); + assertEquals(t3, t4); + assertEquals(t5, t6); + assertEquals(t7, t8); - } - - private static class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { - - private final Class beanClass; - - private final Method readMethod; - - private final Method writeMethod; - - private final Class propertyEditorClass; - - private volatile Set ambiguousWriteMethods; - - private Class propertyType; - - private MethodParameter writeMethodParameter; - - - public GenericTypeAwarePropertyDescriptor(Class beanClass, String propertyName, - Method readMethod, Method writeMethod, Class propertyEditorClass) - throws IntrospectionException { - - super(propertyName, null, null); - this.beanClass = beanClass; - this.propertyEditorClass = propertyEditorClass; - - Method readMethodToUse = BridgeMethodResolver.findBridgedMethod(readMethod); - Method writeMethodToUse = BridgeMethodResolver.findBridgedMethod(writeMethod); - if (writeMethodToUse == null && readMethodToUse != null) { - // Fallback: Original JavaBeans introspection might not have found matching setter - // method due to lack of bridge method resolution, in case of the getter using a - // covariant return type whereas the setter is defined for the concrete property type. - writeMethodToUse = ClassUtils.getMethodIfAvailable(this.beanClass, - "set" + StringUtils.capitalize(getName()), readMethodToUse.getReturnType()); - } - this.readMethod = readMethodToUse; - this.writeMethod = writeMethodToUse; - - if (this.writeMethod != null && this.readMethod == null) { - // Write method not matched against read method: potentially ambiguous through - // several overloaded variants, in which case an arbitrary winner has been chosen - // by the JDK's JavaBeans Introspector... - Set ambiguousCandidates = new HashSet(); - for (Method method : beanClass.getMethods()) { - if (method.getName().equals(writeMethodToUse.getName()) && - !method.equals(writeMethodToUse) && !method.isBridge()) { - ambiguousCandidates.add(method); - } - } - if (!ambiguousCandidates.isEmpty()) { - this.ambiguousWriteMethods = ambiguousCandidates; - } - } - } - - - @Override - public Method getReadMethod() { - return this.readMethod; - } - - @Override - public Method getWriteMethod() { - return this.writeMethod; - } - - public Method getWriteMethodForActualAccess() { - Set ambiguousCandidates = this.ambiguousWriteMethods; - if (ambiguousCandidates != null) { - this.ambiguousWriteMethods = null; - LogFactory.getLog(GenericTypeAwarePropertyDescriptor.class).warn("Invalid JavaBean property '" + - getName() + "' being accessed! Ambiguous write methods found next to actually used [" + - this.writeMethod + "]: " + ambiguousCandidates); - } - return this.writeMethod; - } - - @Override - public Class getPropertyEditorClass() { - return this.propertyEditorClass; - } - - @Override - public synchronized Class getPropertyType() { - if (this.propertyType == null) { - if (this.readMethod != null) { - this.propertyType = GenericTypeResolver.resolveReturnType(this.readMethod, this.beanClass); - } - else { - MethodParameter writeMethodParam = getWriteMethodParameter(); - if (writeMethodParam != null) { - this.propertyType = writeMethodParam.getParameterType(); - } - else { - this.propertyType = super.getPropertyType(); - } - } - } - return this.propertyType; - } - - public synchronized MethodParameter getWriteMethodParameter() { - if (this.writeMethod == null) { - return null; - } - if (this.writeMethodParameter == null) { - this.writeMethodParameter = new MethodParameter(this.writeMethod, 0); - GenericTypeResolver.resolveParameterType(this.writeMethodParameter, this.beanClass); - } - return this.writeMethodParameter; - } + TypeDescriptor t9 = new TypeDescriptor(getClass().getField("listField")); + TypeDescriptor t10 = new TypeDescriptor(getClass().getField("listField")); + assertEquals(t9, t10); + TypeDescriptor t11 = new TypeDescriptor(getClass().getField("mapField")); + TypeDescriptor t12 = new TypeDescriptor(getClass().getField("mapField")); + assertEquals(t11, t12); } - }