001package net.gdface.utils;
002
003import static com.google.common.base.Preconditions.checkArgument;
004
005import java.lang.reflect.GenericArrayType;
006import java.lang.reflect.ParameterizedType;
007import java.lang.reflect.Type;
008import java.lang.reflect.TypeVariable;
009import java.lang.reflect.WildcardType;
010import java.util.List;
011import java.util.Map;
012import java.util.Set;
013
014import com.google.common.reflect.TypeParameter;
015import com.google.common.reflect.TypeToken;
016
017/**
018 * 对象类型相关工具
019 * @author guyadong
020 *
021 */
022public class TypeUtils {
023
024        public TypeUtils() {
025        }
026        public static interface Action{
027                void doClass(Class<?> type);
028        }
029        public static void traverseTypes(Type type,Action action){
030                checkArgument(null !=action,"action is null");
031                if(type instanceof Class<?>){
032                        action.doClass((Class<?>) type);
033                }else if( type instanceof ParameterizedType){
034                        ParameterizedType paramType = (ParameterizedType)type;
035                        Type rawType = paramType.getRawType();
036                        Type[] typeArgs = paramType.getActualTypeArguments();
037                        traverseTypes(rawType,action);
038                        for(Type arg:typeArgs){
039                                traverseTypes(arg,action);
040                        }
041                }else if (type instanceof GenericArrayType) {
042                        traverseTypes(((GenericArrayType) type).getGenericComponentType(),action);
043                } else if (type instanceof TypeVariable) {
044                        for (Type t : ((TypeVariable<?>) type).getBounds()) {
045                                traverseTypes(t,action);
046                        }
047                } else if (type instanceof WildcardType) {
048                        for (Type t : ((WildcardType) type).getLowerBounds()) {
049                                traverseTypes(t,action);
050                        }
051                        for (Type t : ((WildcardType) type).getUpperBounds()) {
052                                traverseTypes(t,action);
053                        }
054                } else{
055                        throw new IllegalArgumentException(String.format("not allow type %s", type.toString()));
056                }
057        }
058        @SuppressWarnings("serial")
059        public static <K, V> TypeToken<Map<K, V>> mapToken(TypeToken<K> keyToken, TypeToken<V> valueToken) {
060                  return new TypeToken<Map<K, V>>() {}
061                    .where(new TypeParameter<K>() {}, keyToken)
062                    .where(new TypeParameter<V>() {}, valueToken);
063        }
064        @SuppressWarnings("serial")
065        public static <T> TypeToken<List<T>> listToken(TypeToken<T> keyToken) {
066                  return new TypeToken<List<T>>() {}
067                    .where(new TypeParameter<T>() {}, keyToken);
068        }
069        @SuppressWarnings("serial")
070        public static <T> TypeToken<Set<T>> setToken(TypeToken<T> keyToken) {
071                  return new TypeToken<Set<T>>() {}
072                    .where(new TypeParameter<T>() {}, keyToken);
073        }
074
075}