Browse Source

Introduce GenericTypeResolver#resolveReturnTypeArgument

Issue: SPR-8514
pull/7/head
Chris Beams 14 years ago
parent
commit
605f0e7a22
  1. 31
      org.springframework.core/src/main/java/org/springframework/core/GenericTypeResolver.java
  2. 17
      org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java

31
org.springframework.core/src/main/java/org/springframework/core/GenericTypeResolver.java

@ -24,6 +24,8 @@ import java.lang.reflect.Method; @@ -24,6 +24,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -102,6 +104,35 @@ public abstract class GenericTypeResolver { @@ -102,6 +104,35 @@ public abstract class GenericTypeResolver {
return (rawType instanceof Class ? (Class) rawType : method.getReturnType());
}
/**
* Resolve the single type argument of the given generic interface against the given
* target method which is assumed to return the given interface or an implementation
* of it.
* @param method the target method to check the return type of
* @param genericIfc the generic interface or superclass to resolve the type argument from
* @return the resolved parameter type of the method return type, or <code>null</code>
* if not resolvable or if the single argument is of type {@link WildcardType}.
*/
public static Class<?> resolveReturnTypeArgument(Method method, Class<?> genericIfc) {
Type returnType = method.getReturnType();
Type genericReturnType = method.getGenericReturnType();
ParameterizedType targetType;
if (returnType.equals(genericIfc)) {
if (genericReturnType instanceof ParameterizedType) {
targetType = (ParameterizedType)genericReturnType;
Type[] actualTypeArguments = targetType.getActualTypeArguments();
Type typeArg = actualTypeArguments[0];
if (!(typeArg instanceof WildcardType)) {
return (Class<?>)typeArg;
}
}
else {
return null;
}
}
return GenericTypeResolver.resolveTypeArgument((Class<?>)returnType, genericIfc);
}
/**
* Resolve the single type argument of the given generic interface against
* the given target class which is assumed to implement the generic interface

17
org.springframework.core/src/test/java/org/springframework/core/GenericTypeResolverTests.java

@ -20,6 +20,7 @@ import java.util.Collection; @@ -20,6 +20,7 @@ import java.util.Collection;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.util.ReflectionUtils;
/**
* @author Juergen Hoeller
@ -46,6 +47,14 @@ public class GenericTypeResolverTests { @@ -46,6 +47,14 @@ public class GenericTypeResolverTests {
assertEquals(Collection.class, GenericTypeResolver.resolveTypeArgument(MyCollectionSuperclassType.class, MySuperclassType.class));
}
@Test
public void testMethodReturnType() {
assertEquals(Integer.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "integer"), MyInterfaceType.class));
assertEquals(String.class, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "string"), MyInterfaceType.class));
assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "raw"), MyInterfaceType.class));
assertEquals(null, GenericTypeResolver.resolveReturnTypeArgument(ReflectionUtils.findMethod(MyTypeWithMethods.class, "object"), MyInterfaceType.class));
}
public interface MyInterfaceType<T> {
}
@ -66,4 +75,12 @@ public class GenericTypeResolverTests { @@ -66,4 +75,12 @@ public class GenericTypeResolverTests {
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
}
public class MyTypeWithMethods {
public MyInterfaceType<Integer> integer() { return null; }
public MySimpleInterfaceType string() { return null; }
public Object object() { return null; }
@SuppressWarnings("rawtypes")
public MyInterfaceType raw() { return null; }
}
}

Loading…
Cancel
Save