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
023 package org.granite.generator.util;
024
025 import java.lang.reflect.ParameterizedType;
026 import java.lang.reflect.Type;
027 import java.lang.reflect.TypeVariable;
028 import java.util.ArrayList;
029 import java.util.List;
030
031 import org.granite.util.ClassUtil;
032
033 /**
034 * @author Franck WOLFF
035 */
036 public 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 }