001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 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 */ 022 023package org.granite.generator.util; 024 025import java.lang.reflect.ParameterizedType; 026import java.lang.reflect.Type; 027import java.lang.reflect.TypeVariable; 028import java.util.ArrayList; 029import java.util.List; 030 031import org.granite.util.ClassUtil; 032 033/** 034 * @author Franck WOLFF 035 */ 036public abstract class GenericTypeUtil { 037 038 public static ParameterizedType[] getDeclaringTypes(Class<?> type) { 039 List<ParameterizedType> supertypes = new ArrayList<ParameterizedType>(); 040 041 Type stype = type.getGenericSuperclass(); 042 Class<?> sclass = type.getSuperclass(); 043 while (sclass != null && sclass != Object.class) { 044 if (stype instanceof ParameterizedType) 045 supertypes.add((ParameterizedType)stype); 046 stype = sclass.getGenericSuperclass(); 047 sclass = sclass.getSuperclass(); 048 } 049 050 collectGenericInterfaces(type.getGenericInterfaces(), supertypes); 051 052 return supertypes.isEmpty() ? null : supertypes.toArray(new ParameterizedType[supertypes.size()]); 053 } 054 055 private static void collectGenericInterfaces(Type[] types, List<ParameterizedType> supertypes) { 056 if (types == null) 057 return; 058 for (Type t : types) { 059 if (t instanceof ParameterizedType) 060 supertypes.add((ParameterizedType)t); 061 else 062 collectGenericInterfaces(((Class<?>)t).getGenericInterfaces(), supertypes); 063 } 064 } 065 066 public static Type primitiveToWrapperType(Type type) { 067 if (type.equals(short.class)) 068 return Short.class; 069 else if (type.equals(byte.class)) 070 return Byte.class; 071 else if (type.equals(boolean.class)) 072 return Boolean.class; 073 else if (type == int.class) 074 return Integer.class; 075 else if (type == long.class) 076 return Long.class; 077 else if (type == float.class) 078 return Float.class; 079 else if (type == double.class) 080 return Double.class; 081 return type; 082 } 083 084 public static Type resolveTypeVariable(Type genericType, Class<?> declaringClass, ParameterizedType[] declaringTypes) { 085 if (genericType instanceof TypeVariable && declaringTypes != null) { 086 int index = -1; 087 TypeVariable<?> typeVariable = (TypeVariable<?>)genericType; 088 ParameterizedType declaringType = null; 089 for (int j = 0; j < declaringClass.getTypeParameters().length; j++) { 090 Type typeParameter = declaringClass.getTypeParameters()[j]; 091 if (typeParameter == typeVariable) 092 index = j; 093 else if (typeVariable.getBounds() != null) { 094 for (Type t : typeVariable.getBounds()) { 095 if (typeParameter == t) { 096 index = j; 097 break; 098 } 099 } 100 } 101 if (index >= 0) { 102 for (ParameterizedType t : declaringTypes) { 103 if (declaringClass.isAssignableFrom(ClassUtil.classOfType(t))) { 104 declaringType = t; 105 break; 106 } 107 } 108 break; 109 } 110 } 111 if (declaringType != null && index >= 0 && index < declaringType.getActualTypeArguments().length) 112 return declaringType.getActualTypeArguments()[index]; 113 } 114 return genericType; 115 } 116}