Fixed regression with constructing TypeDescriptor from null Class
Issue: SPR-11354
This commit is contained in:
parent
42db41e007
commit
eeae5fba95
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -306,6 +306,28 @@ public class FormattingConversionServiceTests {
|
||||||
TypeDescriptor.valueOf(String.class));
|
TypeDescriptor.valueOf(String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegisterDefaultValueViaFormatter() {
|
||||||
|
registerDefaultValue(Date.class, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void registerDefaultValue(Class<T> clazz, final T defaultValue) {
|
||||||
|
formattingService.addFormatterForFieldType(clazz, new Formatter<T>() {
|
||||||
|
@Override
|
||||||
|
public T parse(String text, Locale locale) throws ParseException {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String print(T t, Locale locale) {
|
||||||
|
return defaultValue.toString();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return defaultValue.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class ValueBean {
|
public static class ValueBean {
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,10 @@ public class TypeDescriptor implements Serializable {
|
||||||
|
|
||||||
private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<Class<?>, TypeDescriptor>();
|
private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<Class<?>, TypeDescriptor>();
|
||||||
|
|
||||||
private static final Class<?>[] CACHED_COMMON_TYPES = {Boolean.class, byte.class,
|
private static final Class<?>[] CACHED_COMMON_TYPES = {
|
||||||
Byte.class, char.class, Character.class, short.class, Short.class, int.class,
|
boolean.class, Boolean.class, byte.class, Byte.class, char.class, Character.class,
|
||||||
Integer.class, long.class, Long.class, float.class, Float.class, double.class,
|
double.class, Double.class, int.class, Integer.class, long.class, Long.class,
|
||||||
Double.class, String.class};
|
float.class, Float.class, short.class, Short.class, String.class, Object.class};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (Class<?> preCachedClass : CACHED_COMMON_TYPES) {
|
for (Class<?> preCachedClass : CACHED_COMMON_TYPES) {
|
||||||
|
@ -125,7 +125,7 @@ public class TypeDescriptor implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
private Annotation[] nullSafeAnnotations(Annotation[] annotations) {
|
private Annotation[] nullSafeAnnotations(Annotation[] annotations) {
|
||||||
return annotations != null ? annotations : EMPTY_ANNOTATION_ARRAY;
|
return (annotations != null ? annotations : EMPTY_ANNOTATION_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -500,11 +500,13 @@ public class TypeDescriptor implements Serializable {
|
||||||
* field is available to provide additional conversion context.
|
* field is available to provide additional conversion context.
|
||||||
* <p>Generally prefer use of {@link #forObject(Object)} for constructing type
|
* <p>Generally prefer use of {@link #forObject(Object)} for constructing type
|
||||||
* descriptors from source objects, as it handles the {@code null} object case.
|
* descriptors from source objects, as it handles the {@code null} object case.
|
||||||
* @param type the class
|
* @param type the class (may be {@code null} to indicate {@code Object.class})
|
||||||
* @return the type descriptor
|
* @return the corresponding type descriptor
|
||||||
*/
|
*/
|
||||||
public static TypeDescriptor valueOf(Class<?> type) {
|
public static TypeDescriptor valueOf(Class<?> type) {
|
||||||
Assert.notNull(type, "Type must not be null");
|
if (type == null) {
|
||||||
|
type = Object.class;
|
||||||
|
}
|
||||||
TypeDescriptor desc = commonTypesCache.get(type);
|
TypeDescriptor desc = commonTypesCache.get(type);
|
||||||
return (desc != null ? desc : new TypeDescriptor(ResolvableType.forClass(type), null, null));
|
return (desc != null ? desc : new TypeDescriptor(ResolvableType.forClass(type), null, null));
|
||||||
}
|
}
|
||||||
|
@ -522,12 +524,11 @@ public class TypeDescriptor implements Serializable {
|
||||||
* @return the collection type descriptor
|
* @return the collection type descriptor
|
||||||
*/
|
*/
|
||||||
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementTypeDescriptor) {
|
public static TypeDescriptor collection(Class<?> collectionType, TypeDescriptor elementTypeDescriptor) {
|
||||||
Assert.notNull(collectionType, "CollectionType must not be null");
|
Assert.notNull(collectionType, "collectionType must not be null");
|
||||||
if (!Collection.class.isAssignableFrom(collectionType)) {
|
if (!Collection.class.isAssignableFrom(collectionType)) {
|
||||||
throw new IllegalArgumentException("collectionType must be a java.util.Collection");
|
throw new IllegalArgumentException("collectionType must be a java.util.Collection");
|
||||||
}
|
}
|
||||||
ResolvableType element = (elementTypeDescriptor == null ? null
|
ResolvableType element = (elementTypeDescriptor != null ? elementTypeDescriptor.resolvableType : null);
|
||||||
: elementTypeDescriptor.resolvableType);
|
|
||||||
return new TypeDescriptor(ResolvableType.forClassWithGenerics(collectionType, element), null, null);
|
return new TypeDescriptor(ResolvableType.forClassWithGenerics(collectionType, element), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,8 +550,8 @@ public class TypeDescriptor implements Serializable {
|
||||||
if (!Map.class.isAssignableFrom(mapType)) {
|
if (!Map.class.isAssignableFrom(mapType)) {
|
||||||
throw new IllegalArgumentException("mapType must be a java.util.Map");
|
throw new IllegalArgumentException("mapType must be a java.util.Map");
|
||||||
}
|
}
|
||||||
ResolvableType key = (keyTypeDescriptor == null ? null : keyTypeDescriptor.resolvableType);
|
ResolvableType key = (keyTypeDescriptor != null ? keyTypeDescriptor.resolvableType : null);
|
||||||
ResolvableType value = (valueTypeDescriptor == null ? null : valueTypeDescriptor.resolvableType);
|
ResolvableType value = (valueTypeDescriptor != null ? valueTypeDescriptor.resolvableType : null);
|
||||||
return new TypeDescriptor(ResolvableType.forClassWithGenerics(mapType, key, value), null, null);
|
return new TypeDescriptor(ResolvableType.forClassWithGenerics(mapType, key, value), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,8 +656,8 @@ public class TypeDescriptor implements Serializable {
|
||||||
* Create a new type descriptor for an object.
|
* Create a new type descriptor for an object.
|
||||||
* <p>Use this factory method to introspect a source object before asking the
|
* <p>Use this factory method to introspect a source object before asking the
|
||||||
* conversion system to convert it to some another type.
|
* conversion system to convert it to some another type.
|
||||||
* <p>If the provided object is null, returns null, else calls {@link #valueOf(Class)}
|
* <p>If the provided object is {@code null}, returns {@code null}, else calls
|
||||||
* to build a TypeDescriptor from the object's class.
|
* {@link #valueOf(Class)} to build a TypeDescriptor from the object's class.
|
||||||
* @param source the source object
|
* @param source the source object
|
||||||
* @return the type descriptor
|
* @return the type descriptor
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue