added forNestedType(MethodParameter) for resolution of nested parameter types for collection, array, and map parameter types
This commit is contained in:
@@ -105,10 +105,26 @@ public class TypeDescriptor {
|
||||
this.type = field.getType();
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for the given class.
|
||||
* Use this to instruct the conversion system to convert to an object to a specific target type, when no type location such as a method parameter or field is available to provide additional conversion context.
|
||||
* Generally prefer use of {@link #forObject(Object)} for constructing source type descriptors for source objects.
|
||||
* @param type the class
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public static TypeDescriptor valueOf(Class<?> type) {
|
||||
if (type == null) {
|
||||
return NULL;
|
||||
}
|
||||
TypeDescriptor desc = typeDescriptorCache.get(type);
|
||||
return (desc != null ? desc : new TypeDescriptor(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for object.
|
||||
* Create a new type descriptor for an object.
|
||||
* Use this factory method to introspect a source object's type before asking the conversion system to convert it to some another type.
|
||||
* Builds in population of nested type descriptors for collection and map objects through object introspection.
|
||||
* If the object is null, returns {@link TypeDescriptor#NULL}.
|
||||
* If the object is not a collection, simply calls {@link #valueOf(Class)}.
|
||||
* If the object is a collection, this factory method will derive the element type(s) by introspecting the collection.
|
||||
@@ -132,6 +148,16 @@ public class TypeDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a nested type declared on an array, collection, or map-based method parameter.
|
||||
* Use this factory method when you've resolved a nested source object such as a collection element or map value and wish to have it converted.
|
||||
* @param methodParameter the method parameter declaring the collection or map
|
||||
* @return the nested type descriptor
|
||||
*/
|
||||
public static TypeDescriptor forNestedType(MethodParameter methodParameter) {
|
||||
return new TypeDescriptor(resolveNestedType(methodParameter), methodParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a nested type declared on an array, collection, or map-based method parameter.
|
||||
* Use this factory method when you've resolved a nested source object such as a collection element or map value and wish to have it converted.
|
||||
@@ -142,22 +168,7 @@ public class TypeDescriptor {
|
||||
public static TypeDescriptor forNestedType(Class<?> nestedType, MethodParameter methodParameter) {
|
||||
return new TypeDescriptor(nestedType, methodParameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for the given class.
|
||||
* Use this to instruct the conversion system to convert to an object to a specific target type, when no type location such as a method parameter or field is available.
|
||||
* Generally prefer use of {@link #forObject(Object)} for constructing source type descriptors for source objects.
|
||||
* @param type the class
|
||||
* @return the type descriptor
|
||||
*/
|
||||
public static TypeDescriptor valueOf(Class<?> type) {
|
||||
if (type == null) {
|
||||
return NULL;
|
||||
}
|
||||
TypeDescriptor desc = typeDescriptorCache.get(type);
|
||||
return (desc != null ? desc : new TypeDescriptor(type));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine the declared (non-generic) type of the wrapped parameter/field.
|
||||
* @return the declared type, or <code>null</code> if this is {@link TypeDescriptor#NULL}
|
||||
@@ -436,6 +447,18 @@ public class TypeDescriptor {
|
||||
return new TypeDescriptor(nestedType, nested);
|
||||
}
|
||||
|
||||
protected static Class<?> resolveNestedType(MethodParameter methodParameter) {
|
||||
if (Collection.class.isAssignableFrom(methodParameter.getParameterType())) {
|
||||
return GenericCollectionTypeResolver.getCollectionParameterType(methodParameter);
|
||||
} else if (Map.class.isAssignableFrom(methodParameter.getParameterType())) {
|
||||
return GenericCollectionTypeResolver.getMapValueParameterType(methodParameter);
|
||||
} else if (methodParameter.getParameterType().isArray()) {
|
||||
return methodParameter.getParameterType().getComponentType();
|
||||
} else {
|
||||
throw new IllegalStateException("Not a collection, map, or array method parameter type " + methodParameter.getParameterType());
|
||||
}
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private TypeDescriptor resolveElementTypeDescriptor() {
|
||||
|
||||
@@ -20,9 +20,11 @@ import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -51,18 +53,29 @@ public class PropertyTypeDescriptor extends TypeDescriptor {
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a nested type declared on an array, collection, or map-based property.
|
||||
* Use this factory method when you've resolved a nested source object such as a collection element or map value and wish to have it converted.
|
||||
* Builds in protection for increasing the nesting level of the provided MethodParameter if the nestedType is itself a collection.
|
||||
* @param methodParameter the method parameter
|
||||
* @return the property descriptor
|
||||
*/
|
||||
public static PropertyTypeDescriptor forNestedType(MethodParameter methodParameter, PropertyDescriptor propertyDescriptor) {
|
||||
return forNestedType(resolveNestedType(methodParameter), methodParameter, propertyDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for a nested type declared on an array, collection, or map-based property.
|
||||
* Use this factory method when you've resolved a nested source object such as a collection element or map value and wish to have it converted.
|
||||
* Builds in protection for increasing the nesting level of the provided MethodParameter if the nestedType is itself a collection.
|
||||
* @param nestedType the nested type
|
||||
* @param parentMethodParameter the method parameter
|
||||
* @param methodParameter the method parameter
|
||||
* @return the property descriptor
|
||||
*/
|
||||
public static PropertyTypeDescriptor forNestedType(Class<?> nestedType, MethodParameter methodParameter, PropertyDescriptor propertyDescriptor) {
|
||||
return new PropertyTypeDescriptor(nestedType, methodParameter, propertyDescriptor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the underlying PropertyDescriptor.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user