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