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    }