View Javadoc
1   /*
2    *    Copyright 2009-2021 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.type;
17  
18  import java.lang.reflect.ParameterizedType;
19  import java.lang.reflect.Type;
20  
21  /**
22   * References a generic type.
23   *
24   * @param <T> the referenced type
25   * @since 3.1.0
26   * @author Simone Tripodi
27   */
28  public abstract class TypeReference<T> {
29  
30    private final Type rawType;
31  
32    protected TypeReference() {
33      rawType = getSuperclassTypeParameter(getClass());
34    }
35  
36    Type getSuperclassTypeParameter(Class<?> clazz) {
37      Type genericSuperclass = clazz.getGenericSuperclass();
38      if (genericSuperclass instanceof Class) {
39        // try to climb up the hierarchy until meet something useful
40        if (TypeReference.class != genericSuperclass) {
41          return getSuperclassTypeParameter(clazz.getSuperclass());
42        }
43  
44        throw new TypeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
45          + "Remove the extension or add a type parameter to it.");
46      }
47  
48      Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
49      // TODO remove this when Reflector is fixed to return Types
50      if (rawType instanceof ParameterizedType) {
51        rawType = ((ParameterizedType) rawType).getRawType();
52      }
53  
54      return rawType;
55    }
56  
57    public final Type getRawType() {
58      return rawType;
59    }
60  
61    @Override
62    public String toString() {
63      return rawType.toString();
64    }
65  
66  }