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