diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/xml/UtilNamespaceHandlerTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/xml/UtilNamespaceHandlerTests.java index 3bb04d4c59..14efce4d5c 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/xml/UtilNamespaceHandlerTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/xml/UtilNamespaceHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -17,14 +17,15 @@ package org.springframework.beans.factory.xml; import java.lang.reflect.Proxy; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; -import java.util.Arrays; -import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; import org.springframework.beans.factory.config.FieldRetrievingFactoryBean; import org.springframework.beans.factory.config.PropertiesFactoryBean; @@ -35,19 +36,23 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.tests.beans.CollectingReaderEventListener; import org.springframework.tests.sample.beans.CustomEnum; import org.springframework.tests.sample.beans.TestBean; +import org.springframework.util.LinkedCaseInsensitiveMap; + +import static org.junit.Assert.*; /** * @author Rob Harrop * @author Juergen Hoeller * @author Mark Fisher */ -public class UtilNamespaceHandlerTests extends TestCase { +public class UtilNamespaceHandlerTests { private DefaultListableBeanFactory beanFactory; private CollectingReaderEventListener listener = new CollectingReaderEventListener(); - @Override + + @Before public void setUp() { this.beanFactory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory); @@ -55,17 +60,21 @@ public class UtilNamespaceHandlerTests extends TestCase { reader.loadBeanDefinitions(new ClassPathResource("testUtilNamespace.xml", getClass())); } - public void testConstant() throws Exception { + + @Test + public void testConstant() { Integer min = (Integer) this.beanFactory.getBean("min"); assertEquals(Integer.MIN_VALUE, min.intValue()); } - public void testConstantWithDefaultName() throws Exception { + @Test + public void testConstantWithDefaultName() { Integer max = (Integer) this.beanFactory.getBean("java.lang.Integer.MAX_VALUE"); assertEquals(Integer.MAX_VALUE, max.intValue()); } - public void testEvents() throws Exception { + @Test + public void testEvents() { ComponentDefinition propertiesComponent = this.listener.getComponentDefinition("myProperties"); assertNotNull("Event for 'myProperties' not sent", propertiesComponent); AbstractBeanDefinition propertiesBean = (AbstractBeanDefinition) propertiesComponent.getBeanDefinitions()[0]; @@ -77,30 +86,35 @@ public class UtilNamespaceHandlerTests extends TestCase { assertEquals("Incorrect BeanDefinition", FieldRetrievingFactoryBean.class, constantBean.getBeanClass()); } - public void testNestedProperties() throws Exception { + @Test + public void testNestedProperties() { TestBean bean = (TestBean) this.beanFactory.getBean("testBean"); Properties props = bean.getSomeProperties(); assertEquals("Incorrect property value", "bar", props.get("foo")); } - public void testPropertyPath() throws Exception { + @Test + public void testPropertyPath() { String name = (String) this.beanFactory.getBean("name"); assertEquals("Rob Harrop", name); } - public void testNestedPropertyPath() throws Exception { + @Test + public void testNestedPropertyPath() { TestBean bean = (TestBean) this.beanFactory.getBean("testBean"); assertEquals("Rob Harrop", bean.getName()); } - public void testSimpleMap() throws Exception { + @Test + public void testSimpleMap() { Map map = (Map) this.beanFactory.getBean("simpleMap"); assertEquals("bar", map.get("foo")); Map map2 = (Map) this.beanFactory.getBean("simpleMap"); assertTrue(map == map2); } - public void testScopedMap() throws Exception { + @Test + public void testScopedMap() { Map map = (Map) this.beanFactory.getBean("scopedMap"); assertEquals("bar", map.get("foo")); Map map2 = (Map) this.beanFactory.getBean("scopedMap"); @@ -108,14 +122,16 @@ public class UtilNamespaceHandlerTests extends TestCase { assertTrue(map != map2); } - public void testSimpleList() throws Exception { + @Test + public void testSimpleList() { List list = (List) this.beanFactory.getBean("simpleList"); assertEquals("Rob Harrop", list.get(0)); List list2 = (List) this.beanFactory.getBean("simpleList"); assertTrue(list == list2); } - public void testScopedList() throws Exception { + @Test + public void testScopedList() { List list = (List) this.beanFactory.getBean("scopedList"); assertEquals("Rob Harrop", list.get(0)); List list2 = (List) this.beanFactory.getBean("scopedList"); @@ -123,14 +139,16 @@ public class UtilNamespaceHandlerTests extends TestCase { assertTrue(list != list2); } - public void testSimpleSet() throws Exception { + @Test + public void testSimpleSet() { Set set = (Set) this.beanFactory.getBean("simpleSet"); assertTrue(set.contains("Rob Harrop")); Set set2 = (Set) this.beanFactory.getBean("simpleSet"); assertTrue(set == set2); } - public void testScopedSet() throws Exception { + @Test + public void testScopedSet() { Set set = (Set) this.beanFactory.getBean("scopedSet"); assertTrue(set.contains("Rob Harrop")); Set set2 = (Set) this.beanFactory.getBean("scopedSet"); @@ -138,13 +156,22 @@ public class UtilNamespaceHandlerTests extends TestCase { assertTrue(set != set2); } - public void testMapWithRef() throws Exception { + @Test + public void testMapWithRef() { Map map = (Map) this.beanFactory.getBean("mapWithRef"); assertTrue(map instanceof TreeMap); assertEquals(this.beanFactory.getBean("testBean"), map.get("bean")); } - public void testNestedCollections() throws Exception { + @Test + public void testMapWithTypes() { + Map map = (Map) this.beanFactory.getBean("mapWithTypes"); + assertTrue(map instanceof LinkedCaseInsensitiveMap); + assertEquals(this.beanFactory.getBean("testBean"), map.get("bean")); + } + + @Test + public void testNestedCollections() { TestBean bean = (TestBean) this.beanFactory.getBean("nestedCollectionsBean"); List list = bean.getSomeList(); @@ -171,7 +198,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertFalse(map == bean2.getSomeMap()); } - public void testNestedShortcutCollections() throws Exception { + @Test + public void testNestedShortcutCollections() { TestBean bean = (TestBean) this.beanFactory.getBean("nestedShortcutCollections"); assertEquals(1, bean.getStringArray().length); @@ -194,7 +222,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertFalse(set == bean2.getSomeSet()); } - public void testNestedInCollections() throws Exception { + @Test + public void testNestedInCollections() { TestBean bean = (TestBean) this.beanFactory.getBean("nestedCustomTagBean"); List list = bean.getSomeList(); @@ -219,7 +248,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertFalse(map == bean2.getSomeMap()); } - public void testCircularCollections() throws Exception { + @Test + public void testCircularCollections() { TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionsBean"); List list = bean.getSomeList(); @@ -235,7 +265,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertEquals(bean, map.get("foo")); } - public void testCircularCollectionBeansStartingWithList() throws Exception { + @Test + public void testCircularCollectionBeansStartingWithList() { this.beanFactory.getBean("circularList"); TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean"); @@ -255,7 +286,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertEquals(bean, map.get("foo")); } - public void testCircularCollectionBeansStartingWithSet() throws Exception { + @Test + public void testCircularCollectionBeansStartingWithSet() { this.beanFactory.getBean("circularSet"); TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean"); @@ -275,7 +307,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertEquals(bean, map.get("foo")); } - public void testCircularCollectionBeansStartingWithMap() throws Exception { + @Test + public void testCircularCollectionBeansStartingWithMap() { this.beanFactory.getBean("circularMap"); TestBean bean = (TestBean) this.beanFactory.getBean("circularCollectionBeansBean"); @@ -295,12 +328,14 @@ public class UtilNamespaceHandlerTests extends TestCase { assertEquals(bean, map.get("foo")); } - public void testNestedInConstructor() throws Exception { + @Test + public void testNestedInConstructor() { TestBean bean = (TestBean) this.beanFactory.getBean("constructedTestBean"); assertEquals("Rob Harrop", bean.getName()); } - public void testLoadProperties() throws Exception { + @Test + public void testLoadProperties() { Properties props = (Properties) this.beanFactory.getBean("myProperties"); assertEquals("Incorrect property value", "bar", props.get("foo")); assertEquals("Incorrect property value", null, props.get("foo2")); @@ -308,7 +343,8 @@ public class UtilNamespaceHandlerTests extends TestCase { assertTrue(props == props2); } - public void testScopedProperties() throws Exception { + @Test + public void testScopedProperties() { Properties props = (Properties) this.beanFactory.getBean("myScopedProperties"); assertEquals("Incorrect property value", "bar", props.get("foo")); assertEquals("Incorrect property value", null, props.get("foo2")); @@ -318,30 +354,35 @@ public class UtilNamespaceHandlerTests extends TestCase { assertTrue(props != props2); } - public void testLocalProperties() throws Exception { + @Test + public void testLocalProperties() { Properties props = (Properties) this.beanFactory.getBean("myLocalProperties"); assertEquals("Incorrect property value", null, props.get("foo")); assertEquals("Incorrect property value", "bar2", props.get("foo2")); } - public void testMergedProperties() throws Exception { + @Test + public void testMergedProperties() { Properties props = (Properties) this.beanFactory.getBean("myMergedProperties"); assertEquals("Incorrect property value", "bar", props.get("foo")); assertEquals("Incorrect property value", "bar2", props.get("foo2")); } + @Test public void testLocalOverrideDefault() { Properties props = (Properties) this.beanFactory.getBean("defaultLocalOverrideProperties"); assertEquals("Incorrect property value", "bar", props.get("foo")); assertEquals("Incorrect property value", "local2", props.get("foo2")); } + @Test public void testLocalOverrideFalse() { Properties props = (Properties) this.beanFactory.getBean("falseLocalOverrideProperties"); assertEquals("Incorrect property value", "bar", props.get("foo")); assertEquals("Incorrect property value", "local2", props.get("foo2")); } + @Test public void testLocalOverrideTrue() { Properties props = (Properties) this.beanFactory.getBean("trueLocalOverrideProperties"); assertEquals("Incorrect property value", "local", props.get("foo")); diff --git a/spring-beans/src/test/resources/org/springframework/beans/factory/xml/testUtilNamespace.xml b/spring-beans/src/test/resources/org/springframework/beans/factory/xml/testUtilNamespace.xml index 25f20439fa..2262cd038e 100644 --- a/spring-beans/src/test/resources/org/springframework/beans/factory/xml/testUtilNamespace.xml +++ b/spring-beans/src/test/resources/org/springframework/beans/factory/xml/testUtilNamespace.xml @@ -49,6 +49,11 @@ + + + + Rob Harrop diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index b5a3617dd8..39d0f84792 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -44,7 +44,7 @@ public class TypeDescriptor implements Serializable { static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; - private static final Map, TypeDescriptor> typeDescriptorCache = new HashMap, TypeDescriptor>(); + private static final Map, TypeDescriptor> typeDescriptorCache = new HashMap, TypeDescriptor>(18); static { typeDescriptorCache.put(boolean.class, new TypeDescriptor(boolean.class)); @@ -53,17 +53,18 @@ public class TypeDescriptor implements Serializable { typeDescriptorCache.put(Byte.class, new TypeDescriptor(Byte.class)); typeDescriptorCache.put(char.class, new TypeDescriptor(char.class)); typeDescriptorCache.put(Character.class, new TypeDescriptor(Character.class)); - typeDescriptorCache.put(short.class, new TypeDescriptor(short.class)); - typeDescriptorCache.put(Short.class, new TypeDescriptor(Short.class)); + typeDescriptorCache.put(double.class, new TypeDescriptor(double.class)); + typeDescriptorCache.put(Double.class, new TypeDescriptor(Double.class)); typeDescriptorCache.put(int.class, new TypeDescriptor(int.class)); typeDescriptorCache.put(Integer.class, new TypeDescriptor(Integer.class)); typeDescriptorCache.put(long.class, new TypeDescriptor(long.class)); typeDescriptorCache.put(Long.class, new TypeDescriptor(Long.class)); typeDescriptorCache.put(float.class, new TypeDescriptor(float.class)); typeDescriptorCache.put(Float.class, new TypeDescriptor(Float.class)); - typeDescriptorCache.put(double.class, new TypeDescriptor(double.class)); - typeDescriptorCache.put(Double.class, new TypeDescriptor(Double.class)); + typeDescriptorCache.put(short.class, new TypeDescriptor(short.class)); + typeDescriptorCache.put(Short.class, new TypeDescriptor(Short.class)); typeDescriptorCache.put(String.class, new TypeDescriptor(String.class)); + typeDescriptorCache.put(Object.class, new TypeDescriptor(Object.class)); } @@ -119,6 +120,9 @@ public class TypeDescriptor implements Serializable { * @return the type descriptor */ public static TypeDescriptor valueOf(Class type) { + if (type == null) { + type = Object.class; + } TypeDescriptor desc = typeDescriptorCache.get(type); return (desc != null ? desc : new TypeDescriptor(type)); } @@ -145,8 +149,10 @@ public class TypeDescriptor implements Serializable { /** * Create a new type descriptor from a {@link java.util.Map} type. *

Useful for converting to typed Maps. - *

For example, a Map<String, String> could be converted to a Map<Id, EmailAddress> by converting to a targetType built with this method: - * The method call to construct such a TypeDescriptor would look something like: map(Map.class, TypeDescriptor.valueOf(Id.class), TypeDescriptor.valueOf(EmailAddress.class)); + *

For example, a Map<String, String> could be converted to a Map<Id, EmailAddress> + * by converting to a targetType built with this method: + * The method call to construct such a TypeDescriptor would look something like: + * map(Map.class, TypeDescriptor.valueOf(Id.class), TypeDescriptor.valueOf(EmailAddress.class)); * @param mapType the map type, which must implement {@link Map} * @param keyTypeDescriptor a descriptor for the map's key type, used to convert map keys * @param valueTypeDescriptor the map's value type, used to convert map values @@ -168,7 +174,7 @@ public class TypeDescriptor implements Serializable { * @since 3.2.1 */ public static TypeDescriptor array(TypeDescriptor elementTypeDescriptor) { - if(elementTypeDescriptor == null) { + if (elementTypeDescriptor == null) { return null; } Class type = Array.newInstance(elementTypeDescriptor.getType(), 0).getClass(); @@ -194,13 +200,13 @@ public class TypeDescriptor implements Serializable { * @return the nested type descriptor at the specified nesting level, or null * if it could not be obtained * @throws IllegalArgumentException if the nesting level of the input - * {@link MethodParameter} argument is not 1 - * @throws IllegalArgumentException if the types up to the specified nesting - * level are not of collection, array, or map types + * {@link MethodParameter} argument is not 1, or if the types up to the + * specified nesting level are not of collection, array, or map types */ public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) { if (methodParameter.getNestingLevel() != 1) { - throw new IllegalArgumentException("methodParameter nesting level must be 1: use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); + throw new IllegalArgumentException("methodParameter nesting level must be 1: " + + "use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); } return nested(new ParameterDescriptor(methodParameter), nestingLevel); } @@ -256,8 +262,10 @@ public class TypeDescriptor implements Serializable { /** * Create a new type descriptor for an object. - *

Use this factory method to introspect a source object before asking the conversion system to convert it to some another type. - *

If the provided object is null, returns null, else calls {@link #valueOf(Class)} to build a TypeDescriptor from the object's class. + *

Use this factory method to introspect a source object before asking the + * conversion system to convert it to some another type. + *

If the provided object is null, returns null, else calls {@link #valueOf(Class)} + * to build a TypeDescriptor from the object's class. * @param source the source object * @return the type descriptor */ @@ -265,6 +273,7 @@ public class TypeDescriptor implements Serializable { return (source != null ? valueOf(source.getClass()) : null); } + /** * The type of the backing class, method parameter, field, or property described by this TypeDescriptor. *

Returns primitive types as-is. @@ -290,10 +299,11 @@ public class TypeDescriptor implements Serializable { * Narrows this {@link TypeDescriptor} by setting its type to the class of the provided value. *

If the value is {@code null}, no narrowing is performed and this TypeDescriptor is returned unchanged. *

Designed to be called by binding frameworks when they read property, field, or method return values. - * Allows such frameworks to narrow a TypeDescriptor built from a declared property, field, or method return value type. - * For example, a field declared as {@code java.lang.Object} would be narrowed to {@code java.util.HashMap} - * if it was set to a {@code java.util.HashMap} value. The narrowed TypeDescriptor can then be used to convert - * the HashMap to some other type. Annotation and nested type context is preserved by the narrowed copy. + * Allows such frameworks to narrow a TypeDescriptor built from a declared property, field, or method return + * value type. For example, a field declared as {@code java.lang.Object} would be narrowed to + * {@code java.util.HashMap} if it was set to a {@code java.util.HashMap} value. The narrowed + * TypeDescriptor can then be used to convert the HashMap to some other type. Annotation and + * nested type context is preserved by the narrowed copy. * @param value the value to use for narrowing this type descriptor * @return this TypeDescriptor narrowed (returns a copy with its type updated to the class of the provided value) */ @@ -375,12 +385,15 @@ public class TypeDescriptor implements Serializable { } /** - * Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor. - *

For example, valueOf(String.class).isAssignableTo(valueOf(CharSequence.class)) returns true because a String value can be assigned to a CharSequence variable. - * On the other hand, valueOf(Number.class).isAssignableTo(valueOf(Integer.class)) returns false because, while all Integers are Numbers, not all Numbers are Integers. - *

- * For arrays, collections, and maps, element and key/value types are checked if declared. - * For example, a List<String> field value is assignable to a Collection<CharSequence> field, but List<Number> is not assignable to List<Integer>. + * Returns true if an object of this type descriptor can be assigned to the location described by the + * given type descriptor. + *

For example, valueOf(String.class).isAssignableTo(valueOf(CharSequence.class)) returns true + * because a String value can be assigned to a CharSequence variable. On the other hand, + * valueOf(Number.class).isAssignableTo(valueOf(Integer.class)) returns false because, + * while all Integers are Numbers, not all Numbers are Integers. + *

For arrays, collections, and maps, element and key/value types are checked if declared. + * For example, a List<String> field value is assignable to a Collection<CharSequence> + * field, but List<Number> is not assignable to List<Integer>. * @return true if this type is assignable to the type represented by the provided type descriptor * @see #getObjectType() */ @@ -404,6 +417,7 @@ public class TypeDescriptor implements Serializable { } } + // indexable type descriptor operations /** @@ -424,7 +438,8 @@ public class TypeDescriptor implements Serializable { * If this type is an array, returns the array's component type. * If this type is a {@link Collection} and it is parameterized, returns the Collection's element type. * If the Collection is not parameterized, returns null indicating the element type is not declared. - * @return the array component type or Collection element type, or {@code null} if this type is a Collection but its element type is not parameterized + * @return the array component type or Collection element type, or {@code null} if this type is a + * Collection but its element type is not parameterized * @throws IllegalStateException if this type is not a java.util.Collection or Array type */ public TypeDescriptor getElementTypeDescriptor() { @@ -433,10 +448,13 @@ public class TypeDescriptor implements Serializable { } /** - * If this type is a {@link Collection} or an Array, creates a element TypeDescriptor from the provided collection or array element. - *

Narrows the {@link #getElementTypeDescriptor() 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. + * If this type is a {@link Collection} or an Array, creates a element TypeDescriptor from the provided + * collection or array element. + *

Narrows the {@link #getElementTypeDescriptor() 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 a element type descriptor, narrowed to the type of the provided element @@ -447,6 +465,7 @@ public class TypeDescriptor implements Serializable { return narrow(element, getElementTypeDescriptor()); } + // map type descriptor operations /** @@ -470,8 +489,10 @@ public class TypeDescriptor implements Serializable { /** * If this type is a {@link Map}, creates a mapKey {@link TypeDescriptor} from the provided map key. *

Narrows the {@link #getMapKeyTypeDescriptor() 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. + * 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 @@ -495,9 +516,11 @@ public class TypeDescriptor implements Serializable { /** * If this type is a {@link Map}, creates a mapValue {@link TypeDescriptor} from the provided map value. - *

Narrows the {@link #getMapValueTypeDescriptor() 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. + *

Narrows the {@link #getMapValueTypeDescriptor() 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 @@ -511,7 +534,8 @@ public class TypeDescriptor implements Serializable { // deprecations in Spring 3.1 /** - * Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getElementTypeDescriptor() elementTypeDescriptor}. + * Returns the value of {@link TypeDescriptor#getType() getType()} for the + * {@link #getElementTypeDescriptor() elementTypeDescriptor}. * @deprecated in Spring 3.1 in favor of {@link #getElementTypeDescriptor()} * @throws IllegalStateException if this type is not a java.util.Collection or Array type */ @@ -521,7 +545,8 @@ public class TypeDescriptor implements Serializable { } /** - * Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapKeyTypeDescriptor() getMapKeyTypeDescriptor}. + * Returns the value of {@link TypeDescriptor#getType() getType()} for the + * {@link #getMapKeyTypeDescriptor() getMapKeyTypeDescriptor}. * @deprecated in Spring 3.1 in favor of {@link #getMapKeyTypeDescriptor()} * @throws IllegalStateException if this type is not a java.util.Map */ @@ -531,7 +556,8 @@ public class TypeDescriptor implements Serializable { } /** - * Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapValueTypeDescriptor() getMapValueTypeDescriptor}. + * Returns the value of {@link TypeDescriptor#getType() getType()} for the + * {@link #getMapValueTypeDescriptor() getMapValueTypeDescriptor}. * @deprecated in Spring 3.1 in favor of {@link #getMapValueTypeDescriptor()} * @throws IllegalStateException if this type is not a java.util.Map */ @@ -540,20 +566,6 @@ public class TypeDescriptor implements Serializable { return getMapValueTypeDescriptor().getType(); } - // package private helpers - - TypeDescriptor(AbstractDescriptor descriptor) { - this.type = descriptor.getType(); - this.elementTypeDescriptor = descriptor.getElementTypeDescriptor(); - this.mapKeyTypeDescriptor = descriptor.getMapKeyTypeDescriptor(); - this.mapValueTypeDescriptor = descriptor.getMapValueTypeDescriptor(); - this.annotations = descriptor.getAnnotations(); - } - - static Annotation[] nullSafeAnnotations(Annotation[] annotations) { - return annotations != null ? annotations : EMPTY_ANNOTATION_ARRAY; - } - // internal constructors @@ -579,6 +591,21 @@ public class TypeDescriptor implements Serializable { this.annotations = annotations; } + TypeDescriptor(AbstractDescriptor descriptor) { + this.type = descriptor.getType(); + this.elementTypeDescriptor = descriptor.getElementTypeDescriptor(); + this.mapKeyTypeDescriptor = descriptor.getMapKeyTypeDescriptor(); + this.mapValueTypeDescriptor = descriptor.getMapValueTypeDescriptor(); + this.annotations = descriptor.getAnnotations(); + } + + + // internal helpers + + static Annotation[] nullSafeAnnotations(Annotation[] annotations) { + return (annotations != null ? annotations : EMPTY_ANNOTATION_ARRAY); + } + private static TypeDescriptor nested(AbstractDescriptor descriptor, int nestingLevel) { for (int i = 0; i < nestingLevel; i++) { descriptor = descriptor.nested(); @@ -589,9 +616,6 @@ public class TypeDescriptor implements Serializable { return new TypeDescriptor(descriptor); } - - // internal helpers - private void assertCollectionOrArray() { if (!isCollection() && !isArray()) { throw new IllegalStateException("Not a java.util.Collection or Array");