From 0053e335b5ae0f14d1a2064dddd5f35aa3458d17 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 20 Dec 2011 14:35:29 +0100 Subject: [PATCH] DATACMNS-104 - Upgraded to Spring 3.0.7. Removed GenericTypeResolver copy as all necessary local changes have been released with Spring 3.0.7. --- .../data/util/ClassTypeInformation.java | 1 + .../data/util/GenericTypeResolver.java | 325 ------------------ .../util/ParameterizedTypeInformation.java | 2 + .../data/util/TypeDiscoverer.java | 3 +- spring-data-commons-parent/pom.xml | 4 +- 5 files changed, 7 insertions(+), 328 deletions(-) delete mode 100644 spring-data-commons-core/src/main/java/org/springframework/data/util/GenericTypeResolver.java diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/util/ClassTypeInformation.java b/spring-data-commons-core/src/main/java/org/springframework/data/util/ClassTypeInformation.java index a66412696..773f00ff0 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/util/ClassTypeInformation.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/util/ClassTypeInformation.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import org.springframework.core.GenericTypeResolver; import org.springframework.util.Assert; /** diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/util/GenericTypeResolver.java b/spring-data-commons-core/src/main/java/org/springframework/data/util/GenericTypeResolver.java deleted file mode 100644 index 20e5edd8e..000000000 --- a/spring-data-commons-core/src/main/java/org/springframework/data/util/GenericTypeResolver.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright 2002-2010 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.data.util; - -import java.lang.ref.Reference; -import java.lang.ref.WeakReference; -import java.lang.reflect.Array; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.WeakHashMap; - -import org.springframework.core.MethodParameter; -import org.springframework.util.Assert; - -/** - * Copy of Spring's {@link org.springframework.core.GenericTypeResolver}. Needed until - * {@link #getTypeVariableMap(Class)} gets public. - *

- * TODO: remove that class, as soon as Spring 3.0.6 gets released. - * - * @see SPR-8005 - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -abstract class GenericTypeResolver { - - /** - * Cache from Class to TypeVariable Map - */ - private static final Map>> typeVariableCache = Collections - .synchronizedMap(new WeakHashMap>>()); - - /** - * Determine the target type for the given parameter specification. - * - * @param methodParam the method parameter specification - * @return the corresponding generic parameter type - */ - public static Type getTargetType(MethodParameter methodParam) { - Assert.notNull(methodParam, "MethodParameter must not be null"); - if (methodParam.getConstructor() != null) { - return methodParam.getConstructor().getGenericParameterTypes()[methodParam.getParameterIndex()]; - } else { - if (methodParam.getParameterIndex() >= 0) { - return methodParam.getMethod().getGenericParameterTypes()[methodParam.getParameterIndex()]; - } else { - return methodParam.getMethod().getGenericReturnType(); - } - } - } - - /** - * Resolve the single type argument of the given generic interface against the given target class which is assumed to - * implement the generic interface and possibly declare a concrete type for its type variable. - * - * @param clazz the target class to check against - * @param genericIfc the generic interface or superclass to resolve the type argument from - * @return the resolved type of the argument, or null if not resolvable - */ - public static Class resolveTypeArgument(Class clazz, Class genericIfc) { - Class[] typeArgs = resolveTypeArguments(clazz, genericIfc); - if (typeArgs == null) { - return null; - } - if (typeArgs.length != 1) { - throw new IllegalArgumentException("Expected 1 type argument on generic interface [" + genericIfc.getName() - + "] but found " + typeArgs.length); - } - return typeArgs[0]; - } - - /** - * Resolve the type arguments of the given generic interface against the given target class which is assumed to - * implement the generic interface and possibly declare concrete types for its type variables. - * - * @param clazz the target class to check against - * @param genericIfc the generic interface or superclass to resolve the type argument from - * @return the resolved type of each argument, with the array size matching the number of actual type arguments, or - * null if not resolvable - */ - public static Class[] resolveTypeArguments(Class clazz, Class genericIfc) { - return doResolveTypeArguments(clazz, clazz, genericIfc); - } - - private static Class[] doResolveTypeArguments(Class ownerClass, Class classToIntrospect, Class genericIfc) { - while (classToIntrospect != null) { - if (genericIfc.isInterface()) { - Type[] ifcs = classToIntrospect.getGenericInterfaces(); - for (Type ifc : ifcs) { - Class[] result = doResolveTypeArguments(ownerClass, ifc, genericIfc); - if (result != null) { - return result; - } - } - } else { - Class[] result = doResolveTypeArguments(ownerClass, classToIntrospect.getGenericSuperclass(), genericIfc); - if (result != null) { - return result; - } - } - classToIntrospect = classToIntrospect.getSuperclass(); - } - return null; - } - - private static Class[] doResolveTypeArguments(Class ownerClass, Type ifc, Class genericIfc) { - if (ifc instanceof ParameterizedType) { - ParameterizedType paramIfc = (ParameterizedType) ifc; - Type rawType = paramIfc.getRawType(); - if (genericIfc.equals(rawType)) { - Type[] typeArgs = paramIfc.getActualTypeArguments(); - Class[] result = new Class[typeArgs.length]; - for (int i = 0; i < typeArgs.length; i++) { - Type arg = typeArgs[i]; - result[i] = extractClass(ownerClass, arg); - } - return result; - } else if (genericIfc.isAssignableFrom((Class) rawType)) { - return doResolveTypeArguments(ownerClass, (Class) rawType, genericIfc); - } - } else if (genericIfc.isAssignableFrom((Class) ifc)) { - return doResolveTypeArguments(ownerClass, (Class) ifc, genericIfc); - } - return null; - } - - /** - * Extract a class instance from given Type. - */ - private static Class extractClass(Class ownerClass, Type arg) { - if (arg instanceof ParameterizedType) { - return extractClass(ownerClass, ((ParameterizedType) arg).getRawType()); - } else if (arg instanceof GenericArrayType) { - GenericArrayType gat = (GenericArrayType) arg; - Type gt = gat.getGenericComponentType(); - Class componentClass = extractClass(ownerClass, gt); - return Array.newInstance(componentClass, 0).getClass(); - } else if (arg instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) arg; - arg = getTypeVariableMap(ownerClass).get(tv); - if (arg == null) { - arg = extractBoundForTypeVariable(tv); - } else { - arg = extractClass(ownerClass, arg); - } - } - return (arg instanceof Class ? (Class) arg : Object.class); - } - - /** - * Resolve the specified generic type against the given TypeVariable map. - * - * @param genericType the generic type to resolve - * @param typeVariableMap the TypeVariable Map to resolved against - * @return the type if it resolves to a Class, or Object.class otherwise - */ - static Class resolveType(Type genericType, Map typeVariableMap) { - Type rawType = getRawType(genericType, typeVariableMap); - return (rawType instanceof Class ? (Class) rawType : Object.class); - } - - /** - * Determine the raw type for the given generic parameter type. - * - * @param genericType the generic type to resolve - * @param typeVariableMap the TypeVariable Map to resolved against - * @return the resolved raw type - */ - static Type getRawType(Type genericType, Map typeVariableMap) { - Type resolvedType = genericType; - if (genericType instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) genericType; - resolvedType = typeVariableMap.get(tv); - if (resolvedType == null) { - resolvedType = extractBoundForTypeVariable(tv); - } - } - if (resolvedType instanceof ParameterizedType) { - return ((ParameterizedType) resolvedType).getRawType(); - } else { - return resolvedType; - } - } - - /** - * Build a mapping of {@link TypeVariable#getName TypeVariable names} to concrete {@link Class} for the specified - * {@link Class}. Searches all super types, enclosing types and interfaces. - */ - static Map getTypeVariableMap(Class clazz) { - Reference> ref = typeVariableCache.get(clazz); - Map typeVariableMap = (ref != null ? ref.get() : null); - - if (typeVariableMap == null) { - typeVariableMap = new HashMap(); - - // interfaces - extractTypeVariablesFromGenericInterfaces(clazz.getGenericInterfaces(), typeVariableMap); - - // super class - Type genericType = clazz.getGenericSuperclass(); - Class type = clazz.getSuperclass(); - while (type != null && !Object.class.equals(type)) { - if (genericType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericType; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - } - extractTypeVariablesFromGenericInterfaces(type.getGenericInterfaces(), typeVariableMap); - genericType = type.getGenericSuperclass(); - type = type.getSuperclass(); - } - - // enclosing class - type = clazz; - while (type.isMemberClass()) { - genericType = type.getGenericSuperclass(); - if (genericType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericType; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - } - type = type.getEnclosingClass(); - } - - typeVariableCache.put(clazz, new WeakReference>(typeVariableMap)); - } - - return typeVariableMap; - } - - /** - * Extracts the bound Type for a given {@link TypeVariable}. - */ - static Type extractBoundForTypeVariable(TypeVariable typeVariable) { - Type[] bounds = typeVariable.getBounds(); - if (bounds.length == 0) { - return Object.class; - } - Type bound = bounds[0]; - if (bound instanceof TypeVariable) { - bound = extractBoundForTypeVariable((TypeVariable) bound); - } - return bound; - } - - private static void extractTypeVariablesFromGenericInterfaces(Type[] genericInterfaces, - Map typeVariableMap) { - for (Type genericInterface : genericInterfaces) { - if (genericInterface instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) genericInterface; - populateTypeMapFromParameterizedType(pt, typeVariableMap); - if (pt.getRawType() instanceof Class) { - extractTypeVariablesFromGenericInterfaces(((Class) pt.getRawType()).getGenericInterfaces(), typeVariableMap); - } - } else if (genericInterface instanceof Class) { - extractTypeVariablesFromGenericInterfaces(((Class) genericInterface).getGenericInterfaces(), typeVariableMap); - } - } - } - - /** - * Read the {@link TypeVariable TypeVariables} from the supplied {@link ParameterizedType} and add mappings - * corresponding to the {@link TypeVariable#getName TypeVariable name} -> concrete type to the supplied {@link Map}. - *

- * Consider this case: - *

- * - *