View Javadoc
1   /*
2    *    Copyright 2009-2023 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    *       https://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>
25   *          the referenced type
26   *
27   * @since 3.1.0
28   *
29   * @author Simone Tripodi
30   */
31  public abstract class TypeReference<T> {
32  
33    private final Type rawType;
34  
35    protected TypeReference() {
36      rawType = getSuperclassTypeParameter(getClass());
37    }
38  
39    Type getSuperclassTypeParameter(Class<?> clazz) {
40      Type genericSuperclass = clazz.getGenericSuperclass();
41      if (genericSuperclass instanceof Class) {
42        // try to climb up the hierarchy until meet something useful
43        if (TypeReference.class != genericSuperclass) {
44          return getSuperclassTypeParameter(clazz.getSuperclass());
45        }
46  
47        throw new TypeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
48            + "Remove the extension or add a type parameter to it.");
49      }
50  
51      Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
52      // TODO remove this when Reflector is fixed to return Types
53      if (rawType instanceof ParameterizedType) {
54        rawType = ((ParameterizedType) rawType).getRawType();
55      }
56  
57      return rawType;
58    }
59  
60    public final Type getRawType() {
61      return rawType;
62    }
63  
64    @Override
65    public String toString() {
66      return rawType.toString();
67    }
68  
69  }