added back element type checks in TypeDescriptor#isAssignable; clarified semantics in javadoc

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4480 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Keith Donald 2011-06-07 15:33:44 +00:00
parent 031f0d52e5
commit 2e88435aa4
2 changed files with 30 additions and 6 deletions

View File

@ -279,13 +279,30 @@ public class TypeDescriptor {
} }
/** /**
* Returns true if an object of this type can be assigned to a reference of the given type. * Returns true if an object of this type descriptor can be assigned to the location described by the given type descriptor.
* @param typeDescriptor the descriptor for the target type * 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.
* <p>
* For arrays, collections, and maps, element and key/value types are checked if declared.
* For example, a List&lt;String&gt; field value is assignable to a Collection&lt;CharSequence&gt; field, but List&lt;Number&gt; is not assignable to List&lt;Integer&gt;.
* @return true if this type is assignable to the type represented by the provided type descriptor. * @return true if this type is assignable to the type represented by the provided type descriptor.
* @see #getObjectType() * @see #getObjectType()
*/ */
public boolean isAssignableTo(TypeDescriptor typeDescriptor) { public boolean isAssignableTo(TypeDescriptor typeDescriptor) {
return typeDescriptor.getObjectType().isAssignableFrom(getObjectType()); boolean typesAssignable = typeDescriptor.getObjectType().isAssignableFrom(getObjectType());
if (!typesAssignable) {
return false;
}
if (isArray()) {
return getElementTypeDescriptor().isAssignableTo(typeDescriptor.getElementTypeDescriptor());
} else if (isCollection()) {
return isNestedAssignable(getElementTypeDescriptor(), typeDescriptor.getElementTypeDescriptor());
} else if (isMap()) {
return isNestedAssignable(getMapKeyTypeDescriptor(), typeDescriptor.getMapKeyTypeDescriptor()) &&
isNestedAssignable(getMapValueTypeDescriptor(), typeDescriptor.getMapValueTypeDescriptor());
} else {
return true;
}
} }
// indexable type descriptor operations // indexable type descriptor operations
@ -535,6 +552,13 @@ public class TypeDescriptor {
} }
} }
private boolean isNestedAssignable(TypeDescriptor nestedTypeDescriptor, TypeDescriptor otherNestedTypeDescriptor) {
if (nestedTypeDescriptor == null || otherNestedTypeDescriptor == null) {
return true;
}
return nestedTypeDescriptor.isAssignableTo(otherNestedTypeDescriptor);
}
private String wildcard(TypeDescriptor typeDescriptor) { private String wildcard(TypeDescriptor typeDescriptor) {
return typeDescriptor != null ? typeDescriptor.toString() : "?"; return typeDescriptor != null ? typeDescriptor.toString() : "?";
} }

View File

@ -759,7 +759,7 @@ public class TypeDescriptorTests {
@Test @Test
public void isAssignableElementTypes() throws Exception { public void isAssignableElementTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); assertFalse(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField")))); assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
} }
@ -768,7 +768,7 @@ public class TypeDescriptorTests {
@Test @Test
public void isAssignableMapKeyValueTypes() throws Exception { public void isAssignableMapKeyValueTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); assertFalse(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField")))); assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
} }