Mega Code Archive

 
Categories / Java / Reflection
 

Get Actual Class

/*  * Copyright 2008-2010 the T2 Project ant the Others.  *  * 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.t2framework.commons.util; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class GenericsUtil {   public static Class<?> getActualClass(Type type, Class<?> targetClass) {     Map<TypeVariable<?>, Type> map = getTypeVariableMap(targetClass);     return getActualClass(type, map);   }   public static Type getActualType(Type type, Class<?> targetClass) {     Map<TypeVariable<?>, Type> map = getTypeVariableMap(targetClass);     return getActualType(type, map);   }   private static Class<?> getActualClass(Type type,       Map<TypeVariable<?>, Type> map) {     if (Class.class.isInstance(type)) {       return Class.class.cast(type);     }     if (ParameterizedType.class.isInstance(type)) {       final Type actualType = getActualType(type, map);       return getActualClass(actualType, map);     } else if (TypeVariable.class.isInstance(type)) {       final Type actualType = getActualType(type, map);       return getActualClass(actualType, map);     } else if (GenericArrayType.class.isInstance(type)) {       GenericArrayType genericArrayType = GenericArrayType.class           .cast(type);       final Type genericComponentType = genericArrayType           .getGenericComponentType();       Class<?> componentClass = getActualClass(genericComponentType, map);       return Array.newInstance(componentClass, 0).getClass();     } else {       return null;     }   }   private static Type getActualType(Type type, Map<TypeVariable<?>, Type> map) {     if (Class.class.isInstance(type)) {       return type;     } else if (ParameterizedType.class.isInstance(type)) {       return ParameterizedType.class.cast(type).getRawType();     } else if (TypeVariable.class.isInstance(type)) {       return map.get(TypeVariable.class.cast(type));     } else {       return null;     }   }   private static Map<TypeVariable<?>, Type> getTypeVariableMap(       final Class<?> clazz) {     if (clazz == null) {       return Collections.emptyMap();     }     final Map<TypeVariable<?>, Type> map = new LinkedHashMap<TypeVariable<?>, Type>();     final Class<?> superClass = clazz.getSuperclass();     final Type superClassType = clazz.getGenericSuperclass();     if (superClass != null) {       gatherTypeVariables(superClass, superClassType, map);     }     final Class<?>[] interfaces = clazz.getInterfaces();     final Type[] interfaceTypes = clazz.getGenericInterfaces();     for (int i = 0; i < interfaces.length; ++i) {       gatherTypeVariables(interfaces[i], interfaceTypes[i], map);     }     return map;   }   private static void gatherTypeVariables(final Class<?> clazz,       final Type type, final Map<TypeVariable<?>, Type> map) {     if (clazz == null) {       return;     }     gatherTypeVariables(type, map);     final Class<?> superClass = clazz.getSuperclass();     final Type superClassType = clazz.getGenericSuperclass();     if (superClass != null) {       gatherTypeVariables(superClass, superClassType, map);     }     final Class<?>[] interfaces = clazz.getInterfaces();     final Type[] interfaceTypes = clazz.getGenericInterfaces();     for (int i = 0; i < interfaces.length; ++i) {       gatherTypeVariables(interfaces[i], interfaceTypes[i], map);     }   }   private static void gatherTypeVariables(final Type type,       final Map<TypeVariable<?>, Type> map) {     if (ParameterizedType.class.isInstance(type)) {       final ParameterizedType parameterizedType = ParameterizedType.class           .cast(type);       final TypeVariable<?>[] typeVariables = GenericDeclaration.class           .cast(parameterizedType.getRawType()).getTypeParameters();       final Type[] actualTypes = parameterizedType           .getActualTypeArguments();       for (int i = 0; i < actualTypes.length; ++i) {         map.put(typeVariables[i], actualTypes[i]);       }     }   } }