From b36ab83ab3700ffb3a4b4ac3eaae4d8480792368 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 21 Nov 2012 13:23:02 -0500 Subject: [PATCH] Support GenericArrayType in GenericTypeResolver method Before this change GenericTypeResolver.resolveType supported TypeVariable's and ParameterizedType's only. Now it also supports GenericArrayType. --- .../core/GenericTypeResolver.java | 9 ++++- .../core/GenericTypeResolverTests.java | 40 +++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java b/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java index 1156f8ebdf..0320381d0c 100644 --- a/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java +++ b/spring-core/src/main/java/org/springframework/core/GenericTypeResolver.java @@ -371,8 +371,13 @@ public abstract class GenericTypeResolver { * @return the type if it resolves to a Class, or Object.class otherwise */ public static Class resolveType(Type genericType, Map typeVariableMap) { - Type rawType = getRawType(genericType, typeVariableMap); - return (rawType instanceof Class ? (Class) rawType : Object.class); + Type resolvedType = getRawType(genericType, typeVariableMap); + if (resolvedType instanceof GenericArrayType) { + Type componentType = ((GenericArrayType) resolvedType).getGenericComponentType(); + Class componentClass = resolveType(componentType, typeVariableMap); + resolvedType = Array.newInstance(componentClass, 0).getClass(); + } + return (resolvedType instanceof Class ? (Class) resolvedType : Object.class); } /** diff --git a/spring-core/src/test/java/org/springframework/core/GenericTypeResolverTests.java b/spring-core/src/test/java/org/springframework/core/GenericTypeResolverTests.java index 344dcef541..cdb201c602 100644 --- a/spring-core/src/test/java/org/springframework/core/GenericTypeResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/GenericTypeResolverTests.java @@ -17,6 +17,8 @@ package org.springframework.core; import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.util.Collection; import java.util.HashMap; @@ -128,6 +130,27 @@ public class GenericTypeResolverTests { assertEquals(Object.class, resolveReturnTypeForGenericMethod(extractMagicValue, new Object[] { map })); } + /** + * @since 3.2 + */ + @Test + public void testResolveType() { + Method intMessageMethod = findMethod(MyTypeWithMethods.class, "readIntegerInputMessage", MyInterfaceType.class); + MethodParameter intMessageMethodParam = new MethodParameter(intMessageMethod, 0); + assertEquals(MyInterfaceType.class, + resolveType(intMessageMethodParam.getGenericParameterType(), new HashMap())); + + Method intArrMessageMethod = findMethod(MyTypeWithMethods.class, "readIntegerArrayInputMessage", MyInterfaceType[].class); + MethodParameter intArrMessageMethodParam = new MethodParameter(intArrMessageMethod, 0); + assertEquals(MyInterfaceType[].class, + resolveType(intArrMessageMethodParam.getGenericParameterType(), new HashMap())); + + Method genericArrMessageMethod = findMethod(MySimpleTypeWithMethods.class, "readGenericArrayInputMessage", Object[].class); + MethodParameter genericArrMessageMethodParam = new MethodParameter(genericArrMessageMethod, 0); + Map varMap = getTypeVariableMap(MySimpleTypeWithMethods.class); + assertEquals(Integer[].class, resolveType(genericArrMessageMethodParam.getGenericParameterType(), varMap)); + } + public interface MyInterfaceType { } @@ -147,7 +170,7 @@ public class GenericTypeResolverTests { public class MyCollectionSuperclassType extends MySuperclassType> { } - public static class MyTypeWithMethods { + public static class MyTypeWithMethods { public MyInterfaceType integer() { return null; } public MySimpleInterfaceType string() { return null; } public Object object() { return null; } @@ -166,7 +189,7 @@ public class GenericTypeResolverTests { /** * Similar to {@link #createProxy(Object)} but adds an additional argument - * before the argument of type {@code T}. Note that they may potentially + * before the argument of type {@code T}. Note that they may potentially * be of the same time when invoked! */ public static T createNamedProxy(String name, T object) { @@ -181,7 +204,7 @@ public class GenericTypeResolverTests { } /** - * Similar to {@link #createMock(Class)} but adds an additional method + * Similar to {@link #createMock(Class)} but adds an additional method * argument before the parameterized argument. */ public static T createNamedMock(String name, Class toMock) { @@ -211,6 +234,17 @@ public class GenericTypeResolverTests { return null; } + public void readIntegerInputMessage(MyInterfaceType message) { + } + + public void readIntegerArrayInputMessage(MyInterfaceType[] message) { + } + + public void readGenericArrayInputMessage(T[] message) { + } + } + + public static class MySimpleTypeWithMethods extends MyTypeWithMethods { } static class GenericClass {