From 94d690fb2ce1c56973723f2cf1cd4bba77cd2aa5 Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Sun, 5 Jun 2011 07:14:34 +0000 Subject: [PATCH] javadoc and polishing --- .../core/convert/AbstractDescriptor.java | 12 ++++---- .../core/convert/TypeDescriptor.java | 28 ++++++++++++++++--- .../core/convert/TypeDescriptorTests.java | 21 +++++++++++++- .../expression/spel/SpringEL300Tests.java | 1 - 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/AbstractDescriptor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/AbstractDescriptor.java index 1bdf992bffe..5bd3e7fcf5d 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/AbstractDescriptor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/AbstractDescriptor.java @@ -24,9 +24,9 @@ abstract class AbstractDescriptor { private final Class type; public AbstractDescriptor(Class type) { - //if (type == null) { - // throw new IllegalArgumentException("type cannot be null"); - //} + if (type == null) { + throw new IllegalArgumentException("type cannot be null"); + } this.type = type; } @@ -68,11 +68,13 @@ abstract class AbstractDescriptor { public AbstractDescriptor nested() { if (isCollection()) { - return nested(resolveCollectionElementType(), 0); + Class elementType = resolveCollectionElementType(); + return elementType != null ? nested(elementType, 0) : null; } else if (isArray()) { return nested(getType().getComponentType(), 0); } else if (isMap()) { - return nested(resolveMapValueType(), 1); + Class mapValueType = resolveMapValueType(); + return mapValueType != null ? nested(mapValueType, 1) : null; } else { throw new IllegalStateException("Not a collection, array, or map: cannot resolve nested value types"); } diff --git a/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index 2d7c34b45af..21ab48d7ab8 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -316,9 +316,15 @@ public class TypeDescriptor { } /** - * Creates a elementType descriptor from the provided collection or array element. + * If this type is a {@link Collection} or an Array, creates a elementType descriptor from the provided collection or array element. + * Narrows the {@link #getElementType() elementType} property to the class of the provided collection or array element. + * For example, if this describes a java.util.List<java.lang.Number< and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. + * If this describes a java.util.List<?> and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. + * Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned. * @param element the collection or array element - * @return the element type descriptor + * @return a element type descriptor, narrowed to the type of the provided element + * @throws IllegalStateException if this type is not a java.util.Collection or Array type + * @see #narrow(Object) */ public TypeDescriptor elementType(Object element) { assertCollectionOrArray(); @@ -350,9 +356,15 @@ public class TypeDescriptor { } /** - * Creates a mapKeyType descriptor from the provided map key. + * If this type is a {@link Map}, creates a mapKeyType descriptor from the provided map key. + * Narrows the {@link #getMapKeyType() mapKeyType} property to the class of the provided map key. + * For example, if this describes a java.util.Map<java.lang.Number, java.lang.String< and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. + * If this describes a java.util.Map<?, ?> and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. + * Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned. * @param mapKey the map key * @return the map key type descriptor + * @throws IllegalStateException if this type is not a java.util.Map. + * @see #narrow(Object) */ public TypeDescriptor mapKeyType(Object mapKey) { assertMap(); @@ -375,9 +387,14 @@ public class TypeDescriptor { } /** - * Creates a mapValueType descriptor from the provided map value. + * If this type is a {@link Map}, creates a mapValueType descriptor from the provided map value. + * Narrows the {@link #getMapValueType() mapValueType} property to the class of the provided map value. + * For example, if this describes a java.util.Map<java.lang.String, java.lang.Number< and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer. + * If this describes a java.util.Map<?, ?> and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer as well. + * Annotation and nested type context will be preserved in the narrowed TypeDescriptor that is returned. * @param mapValue the map value * @return the map value type descriptor + * @throws IllegalStateException if this type is not a java.util.Map. */ public TypeDescriptor mapValueType(Object mapValue) { assertMap(); @@ -473,6 +490,9 @@ public class TypeDescriptor { private static TypeDescriptor nested(AbstractDescriptor descriptor, int nestingLevel) { for (int i = 0; i < nestingLevel; i++) { descriptor = descriptor.nested(); + if (descriptor == null) { + return null; + } } return new TypeDescriptor(descriptor); } 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 46b10d7ae1d..a6284d05507 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 @@ -514,6 +514,12 @@ public class TypeDescriptorTests { assertEquals(String.class, t1.getType()); } + @Test(expected=IllegalStateException.class) + public void nestedTooManyLevels() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3); + assertEquals(String.class, t1.getType()); + } + @Test(expected=IllegalStateException.class) public void nestedMethodParameterTypeNotNestable() throws Exception { TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2); @@ -543,7 +549,20 @@ public class TypeDescriptorTests { public void test5(String param1) { } - + + @Test + public void nestedNotParameterized() throws Exception { + TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 1); + assertEquals(List.class,t1.getType()); + assertEquals("java.util.List", t1.toString()); + TypeDescriptor t2 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 2); + assertNull(t2); + } + + public void test6(List param1) { + + } + @Test public void nestedFieldTypeMapTwoLevels() throws Exception { TypeDescriptor t1 = TypeDescriptor.nested(getClass().getField("test4"), 2); diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpringEL300Tests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpringEL300Tests.java index 29315eea0d4..b0f02af27e0 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpringEL300Tests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/SpringEL300Tests.java @@ -726,7 +726,6 @@ public class SpringEL300Tests extends ExpressionTestCase { String el1 = "ls.![#this.equals('abc')]"; SpelExpression exp = parser.parseRaw(el1); List value = (List)exp.getValue(ctx); - System.out.println(value); // value is list containing [true,false] Assert.assertEquals(Boolean.class,value.get(0).getClass()); TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);