001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.generator.util; 022 023import java.lang.reflect.ParameterizedType; 024import java.lang.reflect.Type; 025import java.lang.reflect.TypeVariable; 026import java.util.ArrayList; 027import java.util.List; 028 029import org.granite.util.ClassUtil; 030 031/** 032 * @author Franck WOLFF 033 */ 034public abstract class GenericTypeUtil { 035 036 public static ParameterizedType[] getDeclaringTypes(Class<?> type) { 037 List<ParameterizedType> supertypes = new ArrayList<ParameterizedType>(); 038 039 Type stype = type.getGenericSuperclass(); 040 Class<?> sclass = type.getSuperclass(); 041 while (sclass != null && sclass != Object.class) { 042 if (stype instanceof ParameterizedType) 043 supertypes.add((ParameterizedType)stype); 044 stype = sclass.getGenericSuperclass(); 045 sclass = sclass.getSuperclass(); 046 } 047 048 collectGenericInterfaces(type.getGenericInterfaces(), supertypes); 049 050 return supertypes.isEmpty() ? null : supertypes.toArray(new ParameterizedType[supertypes.size()]); 051 } 052 053 private static void collectGenericInterfaces(Type[] types, List<ParameterizedType> supertypes) { 054 if (types == null) 055 return; 056 for (Type t : types) { 057 if (t instanceof ParameterizedType) 058 supertypes.add((ParameterizedType)t); 059 else 060 collectGenericInterfaces(((Class<?>)t).getGenericInterfaces(), supertypes); 061 } 062 } 063 064 public static Type primitiveToWrapperType(Type type) { 065 if (type.equals(short.class)) 066 return Short.class; 067 else if (type.equals(byte.class)) 068 return Byte.class; 069 else if (type.equals(boolean.class)) 070 return Boolean.class; 071 else if (type == int.class) 072 return Integer.class; 073 else if (type == long.class) 074 return Long.class; 075 else if (type == float.class) 076 return Float.class; 077 else if (type == double.class) 078 return Double.class; 079 return type; 080 } 081 082 public static Type resolveTypeVariable(Type genericType, Class<?> declaringClass, ParameterizedType[] declaringTypes) { 083 if (genericType instanceof TypeVariable && declaringTypes != null) { 084 int index = -1; 085 TypeVariable<?> typeVariable = (TypeVariable<?>)genericType; 086 ParameterizedType declaringType = null; 087 for (int j = 0; j < declaringClass.getTypeParameters().length; j++) { 088 Type typeParameter = declaringClass.getTypeParameters()[j]; 089 if (typeParameter == typeVariable) 090 index = j; 091 else if (typeVariable.getBounds() != null) { 092 for (Type t : typeVariable.getBounds()) { 093 if (typeParameter == t) { 094 index = j; 095 break; 096 } 097 } 098 } 099 if (index >= 0) { 100 for (ParameterizedType t : declaringTypes) { 101 if (declaringClass.isAssignableFrom(ClassUtil.classOfType(t))) { 102 declaringType = t; 103 break; 104 } 105 } 106 break; 107 } 108 } 109 if (declaringType != null && index >= 0 && index < declaringType.getActualTypeArguments().length) 110 return declaringType.getActualTypeArguments()[index]; 111 } 112 return genericType; 113 } 114}