revised wrapper type handling

This commit is contained in:
Juergen Hoeller
2009-08-09 06:36:16 +00:00
parent d41344eb1f
commit 2d7c2d6fff
12 changed files with 111 additions and 119 deletions

View File

@@ -32,20 +32,22 @@ import org.springframework.util.ClassUtils;
*
* @author Keith Donald
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
public class TypeDescriptor {
public final static TypeDescriptor NULL = new TypeDescriptor((Class<?>) null);
private Class<?> type;
private MethodParameter methodParameter;
private Field field;
private Annotation[] cachedFieldAnnotations;
private Class<?> type;
/**
* Creates a new descriptor for the given type.
@@ -101,13 +103,13 @@ public class TypeDescriptor {
*/
public Class<?> getType() {
if (this.type != null) {
return wrapperType(this.type);
return this.type;
}
else if (this.field != null) {
return wrapperType(this.field.getType());
return this.field.getType();
}
else if (this.methodParameter != null) {
return wrapperType(this.methodParameter.getParameterType());
return this.methodParameter.getParameterType();
}
else {
return null;
@@ -233,9 +235,9 @@ public class TypeDescriptor {
/**
* Is the obj an instance of this type?
*/
public boolean isInstance(Object obj) {
public boolean isAssignableValue(Object obj) {
Class<?> type = getType();
return (type != null && getType().isInstance(obj));
return (type != null && ClassUtils.isAssignableValue(getType(), obj));
}
/**
@@ -282,32 +284,6 @@ public class TypeDescriptor {
// internal helpers
private Class<?> wrapperType(Class<?> type) {
if (type.isPrimitive()) {
if (type.equals(int.class)) {
return Integer.class;
} else if (type.equals(short.class)) {
return Short.class;
} else if (type.equals(long.class)) {
return Long.class;
} else if (type.equals(float.class)) {
return Float.class;
} else if (type.equals(double.class)) {
return Double.class;
} else if (type.equals(byte.class)) {
return Byte.class;
} else if (type.equals(boolean.class)) {
return Boolean.class;
} else if (type.equals(char.class)) {
return Character.class;
} else {
throw new IllegalStateException("Should never happen - primitive type is not a primitive?");
}
} else {
return type;
}
}
private Class<?> getArrayComponentType() {
return getType().getComponentType();

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert.support;
import java.lang.reflect.Array;
@@ -23,7 +24,9 @@ import org.springframework.core.convert.TypeDescriptor;
* Special one-way converter that converts from a source array to a target array. Supports type conversion of the
* individual array elements; for example, the ability to convert a String[] to an Integer[]. Mainly used internally by
* {@link org.springframework.core.convert.ConversionService} implementations.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
@SuppressWarnings("unchecked")

View File

@@ -28,6 +28,7 @@ import org.springframework.core.convert.TypeDescriptor;
* specified. Supports type conversion of array elements when a parameterized target collection type descriptor is provided.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
class ArrayToCollection extends AbstractCollectionConverter {

View File

@@ -24,7 +24,9 @@ import org.springframework.core.convert.TypeDescriptor;
/**
* Special converter that converts from target collection to a source array.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
class CollectionToArray extends AbstractCollectionConverter {
@@ -49,16 +51,15 @@ class CollectionToArray extends AbstractCollectionConverter {
private ConversionExecutor getElementConverter(Collection<?> source) {
ConversionExecutor elementConverter = getElementConverter();
if (elementConverter == NoOpConversionExecutor.INSTANCE) {
Iterator<?> it = source.iterator();
while (it.hasNext()) {
Object value = it.next();
for (Object value : source) {
if (value != null) {
elementConverter = getConversionService().getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
elementConverter = getConversionService()
.getConversionExecutor(value.getClass(), TypeDescriptor.valueOf(getTargetElementType()));
break;
}
}
}
return elementConverter != null ? elementConverter : NoOpConversionExecutor.INSTANCE;
return (elementConverter != null ? elementConverter : NoOpConversionExecutor.INSTANCE);
}
}
}

View File

@@ -23,7 +23,9 @@ import org.springframework.core.convert.TypeDescriptor;
/**
* A converter that can convert from one collection type to another.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
@SuppressWarnings("unchecked")

View File

@@ -35,6 +35,7 @@ import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.ConverterInfo;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Base implementation of a conversion service.
@@ -118,17 +119,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
public boolean canConvert(Class<?> sourceType, TypeDescriptor targetType) {
ConversionExecutor executor = getConversionExecutor(sourceType, targetType);
if (executor != null) {
return true;
}
else {
if (parent != null) {
return parent.canConvert(sourceType, targetType);
}
else {
return false;
}
}
return (executor != null || (this.parent != null && this.parent.canConvert(sourceType, targetType)));
}
@SuppressWarnings("unchecked")
@@ -144,15 +135,13 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (executor != null) {
return executor.execute(source);
}
else if (this.parent != null) {
return this.parent.convert(source, targetType);
}
else {
if (this.parent != null) {
return this.parent.convert(source, targetType);
}
else {
throw new ConverterNotFoundException(source.getClass(), targetType.getType(),
"No converter found that can convert from sourceType [" + source.getClass().getName()
+ "] to targetType [" + targetType.getName() + "]");
}
throw new ConverterNotFoundException(source.getClass(), targetType.getType(),
"No converter found that can convert from sourceType [" + source.getClass().getName()
+ "] to targetType [" + targetType.getName() + "]");
}
}
@@ -279,7 +268,7 @@ public class GenericConversionService implements ConversionService, ConverterReg
if (sourceType.isAssignableTo(targetType)) {
return NoOpConversionExecutor.INSTANCE;
}
Converter converter = findRegisteredConverter(sourceType.getType(), targetType.getType());
Converter converter = findRegisteredConverter(ClassUtils.resolvePrimitiveIfNecessary(sourceType.getType()), ClassUtils.resolvePrimitiveIfNecessary(targetType.getType()));
if (converter != null) {
return new StaticConversionExecutor(sourceType, targetType, converter);
}
@@ -361,7 +350,6 @@ public class GenericConversionService implements ConversionService, ConverterReg
while (!classQueue.isEmpty()) {
Class currentClass = classQueue.removeLast();
Map<Class, Object> converters = getConvertersForSource(currentClass);
System.out.println("Source:" + currentClass);
Converter converter = getConverter(converters, targetType);
if (converter != null) {
return converter;

View File

@@ -24,6 +24,7 @@ import org.springframework.core.convert.converter.Converter;
* Default conversion executor implementation for converters.
*
* @author Keith Donald
* @author Juergen Hoeller
* @since 3.0
*/
class StaticConversionExecutor implements ConversionExecutor {
@@ -47,15 +48,15 @@ class StaticConversionExecutor implements ConversionExecutor {
if (source == null) {
return null;
}
if (!this.sourceType.isInstance(source)) {
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), "Source object "
+ source + " to convert is expected to be an instance of [" + sourceType.getName() + "]");
if (!this.sourceType.isAssignableValue(source)) {
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(),
"Source object " + source + " to convert is expected to be an instance of [" + this.sourceType.getName() + "]");
}
try {
return this.converter.convert(source);
}
catch (Exception ex) {
throw new ConversionFailedException(source, sourceType.getType(), targetType.getType(), ex);
throw new ConversionFailedException(source, this.sourceType.getType(), this.targetType.getType(), ex);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2009 the original author or authors.
* Copyright 2002-2009 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert;
import static junit.framework.Assert.assertEquals;
@@ -32,12 +33,6 @@ public class TypeDescriptorTests {
int[] intArray;
List<String>[] arrayOfListOfString;
@Test
public void testWrapperType() {
TypeDescriptor desc = TypeDescriptor.valueOf(int.class);
assertEquals(Integer.class, desc.getType());
}
@Test
public void listDescriptors() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString"));

View File

@@ -136,7 +136,7 @@ public class GenericConversionServiceTests {
@Test
public void convertArrayToPrimitiveArray() {
converter.add(new StringToInteger());
int[] result = (int[]) converter.convert(new String[] { "1", "2", "3" }, int[].class);
int[] result = converter.convert(new String[] { "1", "2", "3" }, int[].class);
assertEquals(1, result[0]);
assertEquals(2, result[1]);
assertEquals(3, result[2]);
@@ -184,7 +184,7 @@ public class GenericConversionServiceTests {
list.add("1");
list.add("2");
list.add("3");
String[] result = (String[]) converter.convert(list, String[].class);
String[] result = converter.convert(list, String[].class);
assertEquals("1", result[0]);
assertEquals("2", result[1]);
assertEquals("3", result[2]);
@@ -229,15 +229,17 @@ public class GenericConversionServiceTests {
@Test
public void convertStringToArrayWithElementConversion() {
converter.add(new StringToInteger());
Integer[] result = (Integer[]) converter.convert("1,2,3", Integer[].class);
Integer[] result = converter.convert("1,2,3", Integer[].class);
assertEquals(3, result.length);
assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]);
}
public static enum FooEnum {
BAR, BAZ
}
}
}