001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.utils;
017
018import java.lang.reflect.ParameterizedType;
019import java.lang.reflect.Type;
020import java.math.BigDecimal;
021import java.math.BigInteger;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025
026public class TypeDef<T> {
027
028    public static final TypeDef LIST_STRING = new TypeDef<List<String>>() {
029    };
030    public static final TypeDef LIST_INTEGER = new TypeDef<List<Integer>>() {
031    };
032    public static final TypeDef LIST_LONG = new TypeDef<List<Long>>() {
033    };
034    public static final TypeDef LIST_DOUBLE = new TypeDef<List<Double>>() {
035    };
036    public static final TypeDef LIST_FLOAT = new TypeDef<List<Float>>() {
037    };
038    public static final TypeDef LIST_BIGINTEGER = new TypeDef<List<BigInteger>>() {
039    };
040    public static final TypeDef LIST_BIGDECIMAL = new TypeDef<List<BigDecimal>>() {
041    };
042
043
044    public static final TypeDef SET_STRING = new TypeDef<Set<String>>() {
045    };
046    public static final TypeDef SET_INTEGER = new TypeDef<Set<Integer>>() {
047    };
048    public static final TypeDef SET_LONG = new TypeDef<Set<Long>>() {
049    };
050    public static final TypeDef SET_DOUBLE = new TypeDef<Set<Double>>() {
051    };
052    public static final TypeDef SET_FLOAT = new TypeDef<Set<Float>>() {
053    };
054    public static final TypeDef SET_BIGINTEGER = new TypeDef<Set<BigInteger>>() {
055    };
056    public static final TypeDef SET_BIGDECIMAL = new TypeDef<Set<BigDecimal>>() {
057    };
058
059
060    public static final TypeDef MAP_STRING = new TypeDef<Map<String, String>>() {
061    };
062    public static final TypeDef MAP_INTEGER = new TypeDef<Map<String, Integer>>() {
063    };
064    public static final TypeDef MAP_LONG = new TypeDef<Map<String, Long>>() {
065    };
066    public static final TypeDef MAP_DOUBLE = new TypeDef<Map<String, Double>>() {
067    };
068    public static final TypeDef MAP_FLOAT = new TypeDef<Map<String, Float>>() {
069    };
070    public static final TypeDef MAP_BIGINTEGER = new TypeDef<Map<String, BigInteger>>() {
071    };
072    public static final TypeDef MAP_BIGDECIMAL = new TypeDef<Map<String, BigDecimal>>() {
073    };
074
075
076    protected Type type;
077    protected Class<?> defClass;
078
079
080    protected TypeDef() {
081        Type superClass = getClass().getGenericSuperclass();
082        if (superClass == TypeDef.class) {
083            throw new IllegalArgumentException("Must appoint generic class in TypeDef.");
084        }
085
086        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
087        if (type instanceof ParameterizedType) {
088            ParameterizedType paraType = (ParameterizedType) type;
089            this.type = paraType;
090            this.defClass = (Class<?>) paraType.getRawType();
091        } else {
092            this.type = type;
093            this.defClass = (Class<?>) type;
094        }
095    }
096
097
098    private TypeDef(Class<?> rawType, Type actualTypeArguments) {
099        this.defClass = rawType;
100        this.type = actualTypeArguments;
101    }
102
103    public void setType(Type type) {
104        this.type = type;
105    }
106
107    public void setDefClass(Class<?> defClass) {
108        this.defClass = defClass;
109    }
110
111    public Type getType() {
112        return type;
113    }
114
115
116    public Class<?> getDefClass() {
117        return defClass;
118    }
119
120
121    public static <T> TypeDef<T> wrapper(Class<T> rawType, Type... actualTypeArguments) {
122        Type type = new ParameterizedType() {
123            @Override
124            public Type[] getActualTypeArguments() {
125                return actualTypeArguments;
126            }
127
128            @Override
129            public Type getRawType() {
130                return rawType;
131            }
132
133            @Override
134            public Type getOwnerType() {
135                return null;
136            }
137        };
138        return new TypeDef<>(rawType, type);
139    }
140
141}