restored TypeDescriptor getElementType, getMapKeyType, and getMapValueType compatibility; StringToCollection and Array Converters are now conditional and check targetElementType if present; TypeDesciptor#isAssignable no longer bothers with element type and map key/value types in checking assignability for consistency elsewhere; improved javadoc

This commit is contained in:
Keith Donald 2011-06-07 02:51:44 +00:00
parent a1a7c32052
commit 5e3a5202fb
21 changed files with 244 additions and 230 deletions

View File

@ -147,7 +147,7 @@ class TypeConverterDelegate {
// Value not of required type?
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
if (requiredType != null && Collection.class.isAssignableFrom(requiredType) && convertedValue instanceof String) {
TypeDescriptor elementType = typeDescriptor.getElementType();
TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor();
if (elementType != null && Enum.class.isAssignableFrom(elementType.getType())) {
convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
}
@ -465,7 +465,7 @@ class TypeConverterDelegate {
return original;
}
typeDescriptor = typeDescriptor.narrow(original);
TypeDescriptor elementType = typeDescriptor.getElementType();
TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor();
if (elementType == null && originalAllowed &&
!this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) {
return original;
@ -512,7 +512,7 @@ class TypeConverterDelegate {
Object element = it.next();
String indexedPropertyName = buildIndexedPropertyName(propertyName, i);
Object convertedElement = convertIfNecessary(
indexedPropertyName, null, element, elementType != null ? elementType.getType() : null , typeDescriptor.getElementType());
indexedPropertyName, null, element, elementType != null ? elementType.getType() : null , typeDescriptor.getElementTypeDescriptor());
try {
convertedCopy.add(convertedElement);
}
@ -537,8 +537,8 @@ class TypeConverterDelegate {
return original;
}
typeDescriptor = typeDescriptor.narrow(original);
TypeDescriptor keyType = typeDescriptor.getMapKeyType();
TypeDescriptor valueType = typeDescriptor.getMapValueType();
TypeDescriptor keyType = typeDescriptor.getMapKeyTypeDescriptor();
TypeDescriptor valueType = typeDescriptor.getMapValueTypeDescriptor();
if (keyType == null && valueType == null && originalAllowed &&
!this.propertyEditorRegistry.hasCustomEditorForElement(null, propertyName)) {
return original;
@ -585,8 +585,8 @@ class TypeConverterDelegate {
Object key = entry.getKey();
Object value = entry.getValue();
String keyedPropertyName = buildKeyedPropertyName(propertyName, key);
Object convertedKey = convertIfNecessary(keyedPropertyName, null, key, keyType != null ? keyType.getType() : null, typeDescriptor.getMapKeyType());
Object convertedValue = convertIfNecessary(keyedPropertyName, null, value, valueType!= null ? valueType.getType() : null, typeDescriptor.getMapValueType());
Object convertedKey = convertIfNecessary(keyedPropertyName, null, key, keyType != null ? keyType.getType() : null, typeDescriptor.getMapKeyTypeDescriptor());
Object convertedValue = convertIfNecessary(keyedPropertyName, null, value, valueType!= null ? valueType.getType() : null, typeDescriptor.getMapValueTypeDescriptor());
try {
convertedCopy.put(convertedKey, convertedValue);
}

View File

@ -34,7 +34,7 @@ abstract class AbstractDescriptor {
return type;
}
public TypeDescriptor getElementType() {
public TypeDescriptor getElementTypeDescriptor() {
if (isCollection()) {
Class<?> elementType = resolveCollectionElementType();
return elementType != null ? new TypeDescriptor(nested(elementType, 0)) : null;
@ -46,7 +46,7 @@ abstract class AbstractDescriptor {
}
}
public TypeDescriptor getMapKeyType() {
public TypeDescriptor getMapKeyTypeDescriptor() {
if (isMap()) {
Class<?> keyType = resolveMapKeyType();
return keyType != null ? new TypeDescriptor(nested(keyType, 0)) : null;
@ -55,7 +55,7 @@ abstract class AbstractDescriptor {
}
}
public TypeDescriptor getMapValueType() {
public TypeDescriptor getMapValueTypeDescriptor() {
if (isMap()) {
Class<?> valueType = resolveMapValueType();
return valueType != null ? new TypeDescriptor(nested(valueType, 1)) : null;

View File

@ -61,6 +61,7 @@ class FieldDescriptor extends AbstractDescriptor {
super(type);
this.field = field;
this.nestingLevel = nestingLevel;
// TODO typeIndex is not preserved at current nestingLevel is not preserved: see SPR-8394
}
}

View File

@ -60,11 +60,11 @@ public class TypeDescriptor {
private final Class<?> type;
private final TypeDescriptor elementType;
private final TypeDescriptor elementTypeDescriptor;
private final TypeDescriptor mapKeyType;
private final TypeDescriptor mapKeyTypeDescriptor;
private final TypeDescriptor mapValueType;
private final TypeDescriptor mapValueTypeDescriptor;
private final Annotation[] annotations;
@ -113,14 +113,14 @@ public class TypeDescriptor {
* For example, a List&lt;String&gt; could be converted to a List&lt;EmailAddress&gt; by converting to a targetType built with this method.
* The method call to construct such a TypeDescriptor would look something like: collection(List.class, TypeDescriptor.valueOf(EmailAddress.class));
* @param collectionType the collection type, which must implement {@link Collection}.
* @param elementType the collection's element type, used to convert collection elements
* @param elementTypeDescriptor a descriptor for the collection's element type, used to convert collection elements
* @return the collection type descriptor
*/
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementType) {
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementTypeDescriptor) {
if (!Collection.class.isAssignableFrom(collectionType)) {
throw new IllegalArgumentException("collectionType must be a java.util.Collection");
}
return new TypeDescriptor(collectionType, elementType);
return new TypeDescriptor(collectionType, elementTypeDescriptor);
}
/**
@ -129,15 +129,15 @@ public class TypeDescriptor {
* For example, a Map&lt;String, String&gt; could be converted to a Map&lt;Id, EmailAddress&gt; 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 keyType the map's key type, used to convert map keys
* @param valueType the map's value type, used to convert map values
* @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
* @return the map type descriptor
*/
public static TypeDescriptor map(Class<?> mapType, TypeDescriptor keyType, TypeDescriptor valueType) {
public static TypeDescriptor map(Class<?> mapType, TypeDescriptor keyTypeDescriptor, TypeDescriptor valueTypeDescriptor) {
if (!Map.class.isAssignableFrom(mapType)) {
throw new IllegalArgumentException("mapType must be a java.util.Map");
}
return new TypeDescriptor(mapType, keyType, valueType);
return new TypeDescriptor(mapType, keyTypeDescriptor, valueTypeDescriptor);
}
/**
@ -151,9 +151,13 @@ public class TypeDescriptor {
* @param methodParameter the method parameter with a nestingLevel of 1
* @param nestingLevel the nesting level of the collection/array element or map key/value declaration within the method parameter.
* @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.
*/
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");
}
return nested(new ParameterDescriptor(methodParameter), nestingLevel);
}
@ -236,7 +240,7 @@ public class TypeDescriptor {
if (value == null) {
return this;
}
return new TypeDescriptor(value.getClass(), elementType, mapKeyType, mapValueType, annotations);
return new TypeDescriptor(value.getClass(), elementTypeDescriptor, mapKeyTypeDescriptor, mapValueTypeDescriptor, annotations);
}
/**
@ -275,24 +279,13 @@ public class TypeDescriptor {
}
/**
* Returns true if an object of this type can be assigned to a reference of given targetType.
* @param targetType the target type
* @return true if this type is assignable to the target
* Returns true if an object of this type can be assigned to a reference of the given type.
* @param typeDescriptor the descriptor for the target type
* @return true if this type is assignable to the type represented by the provided type descriptor.
* @see #getObjectType()
*/
public boolean isAssignableTo(TypeDescriptor targetType) {
boolean typesAssignable = targetType.getObjectType().isAssignableFrom(getObjectType());
if (!typesAssignable) {
return false;
}
if (isArray() && targetType.isArray()) {
return getElementType().isAssignableTo(targetType.getElementType());
}
if (isCollection() && targetType.isCollection()) {
return collectionElementsAssignable(targetType.getElementType());
} else if (isMap() && targetType.isMap()) {
return mapKeysAssignable(targetType.getMapKeyType()) && mapValuesAssignable(targetType.getMapValueType());
}
return true;
public boolean isAssignableTo(TypeDescriptor typeDescriptor) {
return typeDescriptor.getObjectType().isAssignableFrom(getObjectType());
}
// indexable type descriptor operations
@ -318,14 +311,14 @@ public class TypeDescriptor {
* @return the array component type or Collection element type, or <code>null</code> 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 getElementType() {
public TypeDescriptor getElementTypeDescriptor() {
assertCollectionOrArray();
return this.elementType;
return this.elementTypeDescriptor;
}
/**
* 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.
* 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&lt;java.lang.Number&lt; and the element argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* If this describes a java.util.List&lt;?&gt; 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.
@ -334,13 +327,8 @@ public class TypeDescriptor {
* @throws IllegalStateException if this type is not a java.util.Collection or Array type
* @see #narrow(Object)
*/
public TypeDescriptor elementType(Object element) {
assertCollectionOrArray();
if (elementType != null) {
return elementType.narrow(element);
} else {
return element != null ? new TypeDescriptor(element.getClass(), null, null, null, annotations) : null;
}
public TypeDescriptor elementTypeDescriptor(Object element) {
return narrow(element, getElementTypeDescriptor());
}
// map type descriptor operations
@ -358,14 +346,14 @@ public class TypeDescriptor {
* @return the Map key type, or <code>null</code> if this type is a Map but its key type is not parameterized.
* @throws IllegalStateException if this type is not a java.util.Map.
*/
public TypeDescriptor getMapKeyType() {
public TypeDescriptor getMapKeyTypeDescriptor() {
assertMap();
return this.mapKeyType;
return this.mapKeyTypeDescriptor;
}
/**
* 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.
* 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&lt;java.lang.Number, java.lang.String&lt; and the key argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* If this describes a java.util.Map&lt;?, ?&gt; 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.
@ -374,13 +362,8 @@ public class TypeDescriptor {
* @throws IllegalStateException if this type is not a java.util.Map.
* @see #narrow(Object)
*/
public TypeDescriptor mapKeyType(Object mapKey) {
assertMap();
if (mapKeyType != null) {
return mapKeyType.narrow(mapKey);
} else {
return mapKey != null ? new TypeDescriptor(mapKey.getClass(), null, null, null, annotations) : null;
}
public TypeDescriptor mapKeyTypeDescriptor(Object mapKey) {
return narrow(mapKey, getMapKeyTypeDescriptor());
}
/**
@ -389,14 +372,14 @@ public class TypeDescriptor {
* @return the Map value type, or <code>null</code> if this type is a Map but its value type is not parameterized.
* @throws IllegalStateException if this type is not a java.util.Map.
*/
public TypeDescriptor getMapValueType() {
public TypeDescriptor getMapValueTypeDescriptor() {
assertMap();
return this.mapValueType;
return this.mapValueTypeDescriptor;
}
/**
* 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.
* 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&lt;java.lang.String, java.lang.Number&lt; and the value argument is a java.lang.Integer, the returned TypeDescriptor will be java.lang.Integer.
* If this describes a java.util.Map&lt;?, ?&gt; 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.
@ -404,13 +387,8 @@ public class TypeDescriptor {
* @return the map value type descriptor
* @throws IllegalStateException if this type is not a java.util.Map.
*/
public TypeDescriptor mapValueType(Object mapValue) {
assertMap();
if (mapValueType != null) {
return mapValueType.narrow(mapValue);
} else {
return mapValue != null ? new TypeDescriptor(mapValue.getClass(), null, null, null, annotations) : null;
}
public TypeDescriptor mapValueTypeDescriptor(Object mapValue) {
return narrow(mapValue, getMapValueTypeDescriptor());
}
// extending Object
@ -423,16 +401,14 @@ public class TypeDescriptor {
return false;
}
TypeDescriptor other = (TypeDescriptor) obj;
boolean annotatedTypeEquals = ObjectUtils.nullSafeEquals(getType(), other.getType())
&& ObjectUtils.nullSafeEquals(getAnnotations(), other.getAnnotations());
boolean annotatedTypeEquals = ObjectUtils.nullSafeEquals(getType(), other.getType()) && ObjectUtils.nullSafeEquals(getAnnotations(), other.getAnnotations());
if (!annotatedTypeEquals) {
return false;
}
if (isCollection() || isArray()) {
return ObjectUtils.nullSafeEquals(getElementType(), other.getElementType());
return ObjectUtils.nullSafeEquals(getElementTypeDescriptor(), other.getElementTypeDescriptor());
} else if (isMap()) {
return ObjectUtils.nullSafeEquals(getMapKeyType(), other.getMapKeyType())
&& ObjectUtils.nullSafeEquals(getMapValueType(), other.getMapValueType());
return ObjectUtils.nullSafeEquals(getMapKeyTypeDescriptor(), other.getMapKeyTypeDescriptor()) && ObjectUtils.nullSafeEquals(getMapValueTypeDescriptor(), other.getMapValueTypeDescriptor());
} else {
return true;
}
@ -450,21 +426,53 @@ public class TypeDescriptor {
}
builder.append(ClassUtils.getQualifiedName(getType()));
if (isMap()) {
builder.append("<").append(wildcard(getMapKeyType()));
builder.append(", ").append(wildcard(getMapValueType())).append(">");
builder.append("<").append(wildcard(getMapKeyTypeDescriptor()));
builder.append(", ").append(wildcard(getMapValueTypeDescriptor())).append(">");
} else if (isCollection()) {
builder.append("<").append(wildcard(getElementType())).append(">");
builder.append("<").append(wildcard(getElementTypeDescriptor())).append(">");
}
return builder.toString();
}
// helper public class
// deprecations in Spring 3.1
/**
* 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
*/
@Deprecated
public Class<?> getElementType() {
return getElementTypeDescriptor().getType();
}
/**
* Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapKeyTypeDescriptor() mapKeyTypeDescriptor}.
* @deprecated in Spring 3.1 in favor of {@link #getMapKeyTypeDescriptor()}.
* @throws IllegalStateException if this type is not a java.util.Map.
*/
@Deprecated
public Class<?> getMapKeyType() {
return getMapKeyTypeDescriptor().getType();
}
/**
* Returns the value of {@link TypeDescriptor#getType() getType()} for the {@link #getMapValueTypeDescriptor() mapValueTypeDescriptor}.
* @deprecated in Spring 3.1 in favor of {@link #getMapValueTypeDescriptor()}.
* @throws IllegalStateException if this type is not a java.util.Map.
*/
@Deprecated
public Class<?> getMapValueType() {
return getMapValueTypeDescriptor().getType();
}
// package private helpers
TypeDescriptor(AbstractDescriptor descriptor) {
this.type = descriptor.getType();
this.elementType = descriptor.getElementType();
this.mapKeyType = descriptor.getMapKeyType();
this.mapValueType = descriptor.getMapValueType();
this.elementTypeDescriptor = descriptor.getElementTypeDescriptor();
this.mapKeyTypeDescriptor = descriptor.getMapKeyTypeDescriptor();
this.mapValueTypeDescriptor = descriptor.getMapValueTypeDescriptor();
this.annotations = descriptor.getAnnotations();
}
@ -478,20 +486,20 @@ public class TypeDescriptor {
this(new ClassDescriptor(type));
}
private TypeDescriptor(Class<?> collectionType, TypeDescriptor elementType) {
this(collectionType, elementType, null, null, EMPTY_ANNOTATION_ARRAY);
private TypeDescriptor(Class<?> collectionType, TypeDescriptor elementTypeDescriptor) {
this(collectionType, elementTypeDescriptor, null, null, EMPTY_ANNOTATION_ARRAY);
}
private TypeDescriptor(Class<?> mapType, TypeDescriptor keyType, TypeDescriptor valueType) {
this(mapType, null, keyType, valueType, EMPTY_ANNOTATION_ARRAY);
private TypeDescriptor(Class<?> mapType, TypeDescriptor keyTypeDescriptor, TypeDescriptor valueTypeDescriptor) {
this(mapType, null, keyTypeDescriptor, valueTypeDescriptor, EMPTY_ANNOTATION_ARRAY);
}
private TypeDescriptor(Class<?> type, TypeDescriptor elementType, TypeDescriptor mapKeyType,
TypeDescriptor mapValueType, Annotation[] annotations) {
private TypeDescriptor(Class<?> type, TypeDescriptor elementTypeDescriptor, TypeDescriptor mapKeyTypeDescriptor,
TypeDescriptor mapValueTypeDescriptor, Annotation[] annotations) {
this.type = type;
this.elementType = elementType;
this.mapKeyType = mapKeyType;
this.mapValueType = mapValueType;
this.elementTypeDescriptor = elementTypeDescriptor;
this.mapKeyTypeDescriptor = mapKeyTypeDescriptor;
this.mapValueTypeDescriptor = mapValueTypeDescriptor;
this.annotations = annotations;
}
@ -507,39 +515,6 @@ public class TypeDescriptor {
// internal helpers
private boolean mapKeysAssignable(TypeDescriptor targetKeyType) {
TypeDescriptor keyType = getMapKeyType();
if (targetKeyType == null) {
return true;
}
if (keyType == null) {
return false;
}
return keyType.isAssignableTo(targetKeyType);
}
private boolean collectionElementsAssignable(TypeDescriptor targetElementType) {
TypeDescriptor elementType = getElementType();
if (targetElementType == null) {
return true;
}
if (elementType == null) {
return false;
}
return elementType.isAssignableTo(targetElementType);
}
private boolean mapValuesAssignable(TypeDescriptor targetValueType) {
TypeDescriptor valueType = getMapValueType();
if (targetValueType == null) {
return true;
}
if (valueType == null) {
return false;
}
return valueType.isAssignableTo(targetValueType);
}
private void assertCollectionOrArray() {
if (!isCollection() && !isArray()) {
throw new IllegalStateException("Not a java.util.Collection or Array");
@ -552,8 +527,16 @@ public class TypeDescriptor {
}
}
private String wildcard(TypeDescriptor nestedType) {
return nestedType != null ? nestedType.toString() : "?";
private TypeDescriptor narrow(Object value, TypeDescriptor typeDescriptor) {
if (typeDescriptor != null) {
return typeDescriptor.narrow(value);
} else {
return value != null ? new TypeDescriptor(value.getClass(), null, null, null, annotations) : null;
}
}
private String wildcard(TypeDescriptor typeDescriptor) {
return typeDescriptor != null ? typeDescriptor.toString() : "?";
}
}

View File

@ -55,7 +55,7 @@ final class ArrayToCollectionConverter implements GenericConverter {
}
int length = Array.getLength(source);
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), length);
if (targetType.getElementType() == null) {
if (targetType.getElementTypeDescriptor() == null) {
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
target.add(sourceElement);
@ -63,7 +63,7 @@ final class ArrayToCollectionConverter implements GenericConverter {
} else {
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementType(sourceElement), targetType.getElementType());
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor());
target.add(targetElement);
}
}

View File

@ -53,10 +53,10 @@ final class CollectionToArrayConverter implements GenericConverter {
return null;
}
Collection<?> sourceCollection = (Collection<?>) source;
Object array = Array.newInstance(targetType.getElementType().getType(), sourceCollection.size());
Object array = Array.newInstance(targetType.getElementTypeDescriptor().getType(), sourceCollection.size());
int i = 0;
for (Object sourceElement : sourceCollection) {
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementType(sourceElement), targetType.getElementType());
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor());
Array.set(array, i++, targetElement);
}
return array;

View File

@ -55,13 +55,13 @@ final class CollectionToCollectionConverter implements GenericConverter {
}
Collection<?> sourceCollection = (Collection<?>) source;
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
if (targetType.getElementType() == null) {
if (targetType.getElementTypeDescriptor() == null) {
for (Object element : sourceCollection) {
target.add(element);
}
} else {
for (Object sourceElement : sourceCollection) {
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementType(sourceElement), targetType.getElementType());
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor());
target.add(targetElement);
}
}

View File

@ -51,7 +51,7 @@ final class CollectionToObjectConverter implements GenericConverter {
return null;
}
Object firstElement = sourceCollection.iterator().next();
return this.conversionService.convert(firstElement, sourceType.elementType(firstElement), targetType);
return this.conversionService.convert(firstElement, sourceType.elementTypeDescriptor(firstElement), targetType);
}
}

View File

@ -58,7 +58,7 @@ final class CollectionToStringConverter implements GenericConverter {
if (i > 0) {
sb.append(DELIMITER);
}
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementType(sourceElement), targetType);
Object targetElement = this.conversionService.convert(sourceElement, sourceType.elementTypeDescriptor(sourceElement), targetType);
sb.append(targetElement);
i++;
}

View File

@ -58,8 +58,8 @@ final class MapToMapConverter implements GenericConverter {
for (Map.Entry<Object, Object> entry : sourceMap.entrySet()) {
Object sourceKey = entry.getKey();
Object sourceValue = entry.getValue();
Object targetKey = convertKey(sourceKey, sourceType, targetType.getMapKeyType());
Object targetValue = convertValue(sourceValue, sourceType, targetType.getMapValueType());
Object targetKey = convertKey(sourceKey, sourceType, targetType.getMapKeyTypeDescriptor());
Object targetValue = convertValue(sourceValue, sourceType, targetType.getMapValueTypeDescriptor());
targetMap.put(targetKey, targetValue);
}
return targetMap;
@ -71,14 +71,14 @@ final class MapToMapConverter implements GenericConverter {
if (targetType == null) {
return sourceKey;
}
return this.conversionService.convert(sourceKey, sourceType.mapKeyType(sourceKey), targetType);
return this.conversionService.convert(sourceKey, sourceType.mapKeyTypeDescriptor(sourceKey), targetType);
}
private Object convertValue(Object sourceValue, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (targetType == null) {
return sourceValue;
}
return this.conversionService.convert(sourceValue, sourceType.mapValueType(sourceValue), targetType);
return this.conversionService.convert(sourceValue, sourceType.mapValueTypeDescriptor(sourceValue), targetType);
}
}

View File

@ -47,8 +47,8 @@ final class ObjectToArrayConverter implements GenericConverter {
if (source == null) {
return null;
}
Object target = Array.newInstance(targetType.getElementType().getType(), 1);
Object targetElement = this.conversionService.convert(source, sourceType, targetType.getElementType());
Object target = Array.newInstance(targetType.getElementTypeDescriptor().getType(), 1);
Object targetElement = this.conversionService.convert(source, sourceType, targetType.getElementTypeDescriptor());
Array.set(target, 0, targetElement);
return target;
}

View File

@ -51,10 +51,10 @@ final class ObjectToCollectionConverter implements GenericConverter {
return null;
}
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), 1);
if (targetType.getElementType() == null || targetType.getElementType().isCollection()) {
if (targetType.getElementTypeDescriptor() == null || targetType.getElementTypeDescriptor().isCollection()) {
target.add(source);
} else {
Object singleElement = this.conversionService.convert(source, sourceType, targetType.getElementType());
Object singleElement = this.conversionService.convert(source, sourceType, targetType.getElementTypeDescriptor());
target.add(singleElement);
}
return target;

View File

@ -45,7 +45,7 @@ final class StringToArrayConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType, targetType.getElementType());
return this.conversionService.canConvert(sourceType, targetType.getElementTypeDescriptor());
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
@ -54,10 +54,10 @@ final class StringToArrayConverter implements ConditionalGenericConverter {
}
String string = (String) source;
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
Object target = Array.newInstance(targetType.getElementType().getType(), fields.length);
Object target = Array.newInstance(targetType.getElementTypeDescriptor().getType(), fields.length);
for (int i = 0; i < fields.length; i++) {
String sourceElement = fields[i];
Object targetElement = this.conversionService.convert(sourceElement.trim(), sourceType, targetType.getElementType());
Object targetElement = this.conversionService.convert(sourceElement.trim(), sourceType, targetType.getElementTypeDescriptor());
Array.set(target, i, targetElement);
}
return target;

View File

@ -46,8 +46,8 @@ final class StringToCollectionConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
if (targetType.getElementType() != null) {
return this.conversionService.canConvert(sourceType, targetType.getElementType());
if (targetType.getElementTypeDescriptor() != null) {
return this.conversionService.canConvert(sourceType, targetType.getElementTypeDescriptor());
} else {
return true;
}
@ -61,13 +61,13 @@ final class StringToCollectionConverter implements ConditionalGenericConverter {
String string = (String) source;
String[] fields = StringUtils.commaDelimitedListToStringArray(string);
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), fields.length);
if (targetType.getElementType() == null) {
if (targetType.getElementTypeDescriptor() == null) {
for (String field : fields) {
target.add(field.trim());
}
} else {
for (String field : fields) {
Object targetElement = this.conversionService.convert(field.trim(), sourceType, targetType.getElementType());
Object targetElement = this.conversionService.convert(field.trim(), sourceType, targetType.getElementTypeDescriptor());
target.add(targetElement);
}
}

View File

@ -106,12 +106,12 @@ public class TypeDescriptorTests {
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(List.class, desc.getElementType().getType());
assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getElementType());
assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getElementType().getElementType());
assertEquals(TypeDescriptor.nested(methodParameter, 3), desc.getElementType().getElementType().getMapValueType());
assertEquals(Integer.class, desc.getElementType().getElementType().getMapKeyType().getType());
assertEquals(Enum.class, desc.getElementType().getElementType().getMapValueType().getType());
assertEquals(List.class, desc.getElementTypeDescriptor().getType());
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());
}
@ -131,7 +131,7 @@ public class TypeDescriptorTests {
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertNull(desc.getElementType());
assertNull(desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
@ -151,8 +151,8 @@ public class TypeDescriptorTests {
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertTrue(desc.isArray());
assertEquals(Integer.class, desc.getElementType().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
@ -173,11 +173,11 @@ public class TypeDescriptorTests {
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getMapValueType());
assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getMapValueType().getElementType());
assertEquals(Integer.class, desc.getMapKeyType().getType());
assertEquals(List.class, desc.getMapValueType().getType());
assertEquals(String.class, desc.getMapValueType().getElementType().getType());
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<Integer, List<String>> map) {
@ -206,8 +206,8 @@ public class TypeDescriptorTests {
public void propertyComplex() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getComplexProperty", null), getClass().getMethod("setComplexProperty", Map.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(String.class, desc.getMapKeyType().getType());
assertEquals(Integer.class, desc.getMapValueType().getElementType().getElementType().getType());
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementTypeDescriptor().getType());
}
public Map<String, List<List<Integer>>> getComplexProperty() {
@ -232,7 +232,7 @@ public class TypeDescriptorTests {
Property property = new Property(getClass(), genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(List.class, desc.getType());
assertEquals(Integer.class, desc.getElementType().getType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
}
public interface GenericType<T> {
@ -276,7 +276,7 @@ public class TypeDescriptorTests {
Property property = new Property(genericBean.getClass(), genericBean.getClass().getMethod("getListProperty", null), genericBean.getClass().getMethod("setListProperty", List.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(List.class, desc.getType());
assertEquals(Integer.class, desc.getElementType().getType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(MethodAnnotation1.class));
}
@ -308,8 +308,8 @@ public class TypeDescriptorTests {
Property property = new Property(getClass(), getClass().getMethod("getProperty", null), getClass().getMethod("setProperty", Map.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(Map.class, desc.getType());
assertEquals(Integer.class, desc.getMapKeyType().getElementType().getType());
assertEquals(Long.class, desc.getMapValueType().getElementType().getType());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(MethodAnnotation1.class));
assertNotNull(desc.getAnnotation(MethodAnnotation2.class));
assertNotNull(desc.getAnnotation(MethodAnnotation3.class));
@ -364,7 +364,7 @@ public class TypeDescriptorTests {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(String.class, typeDescriptor.getElementType().getType());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getType());
assertEquals("java.util.List<java.lang.String>", typeDescriptor.toString());
}
@ -373,8 +373,8 @@ public class TypeDescriptorTests {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfString"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(List.class, typeDescriptor.getElementType().getType());
assertEquals(String.class, typeDescriptor.getElementType().getElementType().getType());
assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals("java.util.List<java.util.List<java.lang.String>>", typeDescriptor.toString());
}
@ -383,8 +383,8 @@ public class TypeDescriptorTests {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfUnknown"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(List.class, typeDescriptor.getElementType().getType());
assertNull(typeDescriptor.getElementType().getElementType());
assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType());
assertNull(typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor());
assertEquals("java.util.List<java.util.List<?>>", typeDescriptor.toString());
}
@ -392,7 +392,7 @@ public class TypeDescriptorTests {
public void fieldArray() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("intArray"));
assertTrue(typeDescriptor.isArray());
assertEquals(Integer.TYPE,typeDescriptor.getElementType().getType());
assertEquals(Integer.TYPE,typeDescriptor.getElementTypeDescriptor().getType());
assertEquals("int[]",typeDescriptor.toString());
}
@ -401,8 +401,8 @@ public class TypeDescriptorTests {
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.getElementType().getElementType());
assertEquals(List.class,typeDescriptor.getElementTypeDescriptor());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor());
assertEquals("java.util.List[]",typeDescriptor.toString());
}
@ -410,9 +410,9 @@ public class TypeDescriptorTests {
public void fieldComplexTypeDescriptor2() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField"));
assertTrue(typeDescriptor.isMap());
assertEquals(String.class,typeDescriptor.getMapKeyType().getType());
assertEquals(List.class, typeDescriptor.getMapValueType().getType());
assertEquals(Integer.class, typeDescriptor.getMapValueType().getElementType().getType());
assertEquals(String.class,typeDescriptor.getMapKeyTypeDescriptor().getType());
assertEquals(List.class, typeDescriptor.getMapValueTypeDescriptor().getType());
assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.Integer>>", typeDescriptor.toString());
}
@ -422,8 +422,8 @@ public class TypeDescriptorTests {
// TODO: SPR-8394: typeIndex handling not currently supported by fields
TypeDescriptor desc = new TypeDescriptor(getClass().getField("fieldMap"));
assertTrue(desc.isMap());
assertEquals(Integer.class, desc.getMapKeyType().getElementType());
assertEquals(Long.class, desc.getMapValueType().getElementType());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor());
assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor());
}
public Map<List<Integer>, List<Long>> fieldMap;
@ -472,7 +472,7 @@ public class TypeDescriptorTests {
assertTrue(typeDescriptor.isArray());
assertFalse(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isMap());
assertEquals(Integer.TYPE, typeDescriptor.getElementType().getType());
assertEquals(Integer.TYPE, typeDescriptor.getElementTypeDescriptor().getType());
}
@Test
@ -481,7 +481,7 @@ public class TypeDescriptorTests {
assertTrue(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isArray());
assertFalse(typeDescriptor.isMap());
assertNull(typeDescriptor.getElementType());
assertNull(typeDescriptor.getElementTypeDescriptor());
}
@Test
@ -514,6 +514,11 @@ public class TypeDescriptorTests {
assertEquals(String.class, t1.getType());
}
@Test(expected=IllegalArgumentException.class)
public void nestedMethodParameterNot1NestedLevel() throws Exception {
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0, 2), 2);
}
@Test(expected=IllegalStateException.class)
public void nestedTooManyLevels() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3);
@ -597,8 +602,8 @@ public class TypeDescriptorTests {
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(Integer.class, desc.getElementType().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
@ -613,8 +618,8 @@ public class TypeDescriptorTests {
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(List.class, desc.getElementType().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementType().getElementType());
assertEquals(List.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor().getElementTypeDescriptor());
assertFalse(desc.isMap());
}
@ -630,8 +635,8 @@ public class TypeDescriptorTests {
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(String.class, desc.getMapKeyType().getType());
assertEquals(Integer.class, desc.getMapValueType().getType());
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getType());
}
@Test
@ -647,9 +652,9 @@ public class TypeDescriptorTests {
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(String.class, desc.getMapKeyType().getType());
assertEquals(String.class, desc.getMapValueType().getMapKeyType().getType());
assertEquals(Integer.class, desc.getMapValueType().getMapValueType().getType());
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(String.class, desc.getMapValueTypeDescriptor().getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getMapValueTypeDescriptor().getType());
}
@Test
@ -664,17 +669,17 @@ public class TypeDescriptorTests {
public void elementType() {
TypeDescriptor desc = TypeDescriptor.valueOf(List.class);
Integer value = new Integer(3);
desc = desc.elementType(value);
desc = desc.elementTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
@Test
public void elementTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("listPreserveContext"));
assertEquals(Integer.class, desc.getElementType().getElementType().getType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.elementType(value);
assertEquals(Integer.class, desc.getElementType().getType());
desc = desc.elementTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
@ -685,17 +690,17 @@ public class TypeDescriptorTests {
public void mapKeyType() {
TypeDescriptor desc = TypeDescriptor.valueOf(Map.class);
Integer value = new Integer(3);
desc = desc.mapKeyType(value);
desc = desc.mapKeyTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
@Test
public void mapKeyTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext"));
assertEquals(Integer.class, desc.getMapKeyType().getElementType().getType());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.mapKeyType(value);
assertEquals(Integer.class, desc.getElementType().getType());
desc = desc.mapKeyTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
@ -706,17 +711,17 @@ public class TypeDescriptorTests {
public void mapValueType() {
TypeDescriptor desc = TypeDescriptor.valueOf(Map.class);
Integer value = new Integer(3);
desc = desc.mapValueType(value);
desc = desc.mapValueTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
@Test
public void mapValueTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext"));
assertEquals(Integer.class, desc.getMapValueType().getElementType().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.mapValueType(value);
assertEquals(Integer.class, desc.getElementType().getType());
desc = desc.mapValueTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
@ -744,4 +749,29 @@ public class TypeDescriptorTests {
assertEquals(t11, t12);
}
@Test
public void isAssignableTypes() {
assertTrue(TypeDescriptor.valueOf(Integer.class).isAssignableTo(TypeDescriptor.valueOf(Number.class)));
assertFalse(TypeDescriptor.valueOf(Number.class).isAssignableTo(TypeDescriptor.valueOf(Integer.class)));
assertFalse(TypeDescriptor.valueOf(String.class).isAssignableTo(TypeDescriptor.valueOf(String[].class)));
}
@Test
public void isAssignableElementTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
}
public List<Number> isAssignableElementTypes;
@Test
public void isAssignableMapKeyValueTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
}
public Map<CharSequence, Number> isAssignableMapKeyValueTypes;
}

View File

@ -91,11 +91,11 @@ public class Indexer extends SpelNodeImpl {
// Indexing into a Map
if (targetObject instanceof Map) {
Object key = index;
if (targetObjectTypeDescriptor.getMapKeyType() != null) {
key = state.convertValue(key, targetObjectTypeDescriptor.getMapKeyType());
if (targetObjectTypeDescriptor.getMapKeyTypeDescriptor() != null) {
key = state.convertValue(key, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
}
Object value = ((Map<?, ?>) targetObject).get(key);
return new TypedValue(value, targetObjectTypeDescriptor.mapValueType(value));
return new TypedValue(value, targetObjectTypeDescriptor.mapValueTypeDescriptor(value));
}
if (targetObject == null) {
@ -107,7 +107,7 @@ public class Indexer extends SpelNodeImpl {
int idx = (Integer) state.convertValue(index, TypeDescriptor.valueOf(Integer.class));
if (targetObject.getClass().isArray()) {
Object arrayElement = accessArrayElement(targetObject, idx);
return new TypedValue(arrayElement, targetObjectTypeDescriptor.elementType(arrayElement));
return new TypedValue(arrayElement, targetObjectTypeDescriptor.elementTypeDescriptor(arrayElement));
} else if (targetObject instanceof Collection) {
Collection c = (Collection) targetObject;
if (idx >= c.size()) {
@ -118,7 +118,7 @@ public class Indexer extends SpelNodeImpl {
int pos = 0;
for (Object o : c) {
if (pos == idx) {
return new TypedValue(o, targetObjectTypeDescriptor.elementType(o));
return new TypedValue(o, targetObjectTypeDescriptor.elementTypeDescriptor(o));
}
pos++;
}
@ -187,11 +187,11 @@ public class Indexer extends SpelNodeImpl {
if (targetObject instanceof Map) {
Map map = (Map) targetObject;
Object key = index.getValue();
if (targetObjectTypeDescriptor.getMapKeyType() != null) {
key = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyType());
if (targetObjectTypeDescriptor.getMapKeyTypeDescriptor() != null) {
key = state.convertValue(index, targetObjectTypeDescriptor.getMapKeyTypeDescriptor());
}
if (targetObjectTypeDescriptor.getMapValueType() != null) {
newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getMapValueType());
if (targetObjectTypeDescriptor.getMapValueTypeDescriptor() != null) {
newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getMapValueTypeDescriptor());
}
map.put(key, newValue);
return;
@ -199,7 +199,7 @@ public class Indexer extends SpelNodeImpl {
if (targetObjectTypeDescriptor.isArray()) {
int idx = (Integer)state.convertValue(index, TypeDescriptor.valueOf(Integer.class));
setArrayElement(state, contextObject.getValue(), idx, newValue, targetObjectTypeDescriptor.getElementType().getType());
setArrayElement(state, contextObject.getValue(), idx, newValue, targetObjectTypeDescriptor.getElementTypeDescriptor().getType());
return;
}
else if (targetObject instanceof Collection) {
@ -212,8 +212,8 @@ public class Indexer extends SpelNodeImpl {
}
if (targetObject instanceof List) {
List list = (List) targetObject;
if (targetObjectTypeDescriptor.getElementType() != null) {
newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getElementType());
if (targetObjectTypeDescriptor.getElementTypeDescriptor() != null) {
newValue = state.convertValue(newValue, targetObjectTypeDescriptor.getElementTypeDescriptor());
}
list.set(idx, newValue);
return;
@ -271,10 +271,10 @@ public class Indexer extends SpelNodeImpl {
private boolean growCollection(ExpressionState state, TypeDescriptor targetType, int index,
Collection collection) {
if (state.getConfiguration().isAutoGrowCollections()) {
if (targetType.getElementType() == null) {
if (targetType.getElementTypeDescriptor() == null) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE);
}
TypeDescriptor elementType = targetType.getElementType();
TypeDescriptor elementType = targetType.getElementTypeDescriptor();
Object newCollectionElement = null;
try {
int newElements = index - collection.size();

View File

@ -142,7 +142,7 @@ public class Selection extends SpelNodeImpl {
return new TypedValue(result);
}
else {
Class<?> elementType = ClassUtils.resolvePrimitiveIfNecessary(op.getTypeDescriptor().getElementType().getType());
Class<?> elementType = ClassUtils.resolvePrimitiveIfNecessary(op.getTypeDescriptor().getElementTypeDescriptor().getType());
Object resultArray = Array.newInstance(elementType, result.size());
System.arraycopy(result.toArray(), 0, resultArray, 0, result.size());
return new TypedValue(resultArray);

View File

@ -213,7 +213,7 @@ public class ReflectionHelper {
else {
// Now... we have the final argument in the method we are checking as a match and we have 0 or more other
// arguments left to pass to it.
Class varargsParameterType = expectedArgTypes.get(expectedArgTypes.size() - 1).getElementType().getType();
Class varargsParameterType = expectedArgTypes.get(expectedArgTypes.size() - 1).getElementTypeDescriptor().getType();
// All remaining parameters must be of this type or convertable to this type
for (int i = expectedArgTypes.size() - 1; i < suppliedArgTypes.size(); i++) {

View File

@ -74,13 +74,13 @@ public class ExpressionTestsUsingCoreConversionService extends ExpressionTestCas
TypeConvertorUsingConversionService tcs = new TypeConvertorUsingConversionService();
// ArrayList containing List<Integer> to List<String>
Class<?> clazz = typeDescriptorForListOfString.getElementType().getType();
Class<?> clazz = typeDescriptorForListOfString.getElementTypeDescriptor().getType();
assertEquals(String.class,clazz);
List l = (List) tcs.convertValue(listOfInteger, TypeDescriptor.forObject(listOfInteger), typeDescriptorForListOfString);
assertNotNull(l);
// ArrayList containing List<String> to List<Integer>
clazz = typeDescriptorForListOfInteger.getElementType().getType();
clazz = typeDescriptorForListOfInteger.getElementTypeDescriptor().getType();
assertEquals(Integer.class,clazz);
l = (List) tcs.convertValue(listOfString, TypeDescriptor.forObject(listOfString), typeDescriptorForListOfString);

View File

@ -113,7 +113,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType().getType());
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType());
Integer[] array = (Integer[]) value;
assertEquals(5, array.length);
assertEquals(new Integer(0), array[0]);
@ -148,7 +148,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementType().getType());
assertEquals(Integer.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType());
Integer[] array = (Integer[]) value;
assertEquals(5, array.length);
assertEquals(new Integer(0), array[0]);
@ -250,7 +250,7 @@ public class SelectionAndProjectionTests {
Object value = expression.getValue(context);
assertTrue(value.getClass().isArray());
TypedValue typedValue = new TypedValue(value);
assertEquals(Number.class, typedValue.getTypeDescriptor().getElementType().getType());
assertEquals(Number.class, typedValue.getTypeDescriptor().getElementTypeDescriptor().getType());
Number[] array = (Number[]) value;
assertEquals(3, array.length);
assertEquals(new Integer(5), array[0]);

View File

@ -729,7 +729,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
// value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(null, evaluated.getElementType());
Assert.assertEquals(null, evaluated.getElementTypeDescriptor());
}
@Test
@ -742,7 +742,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
// value is array containing [true,false]
Assert.assertEquals(Boolean.class,value[0].getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(Boolean.class, evaluated.getElementType().getType());
Assert.assertEquals(Boolean.class, evaluated.getElementTypeDescriptor().getType());
}
@Test
@ -755,7 +755,7 @@ public class SpringEL300Tests extends ExpressionTestCase {
// value is list containing [true,false]
Assert.assertEquals(Boolean.class,value.get(0).getClass());
TypeDescriptor evaluated = exp.getValueTypeDescriptor(ctx);
Assert.assertEquals(null, evaluated.getElementType());
Assert.assertEquals(null, evaluated.getElementTypeDescriptor());
}
static class C {