TypeReference.java

  1. /*
  2.  *    Copyright 2009-2024 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. import java.lang.reflect.ParameterizedType;
  18. import java.lang.reflect.Type;

  19. /**
  20.  * References a generic type.
  21.  *
  22.  * @param <T>
  23.  *          the referenced type
  24.  *
  25.  * @since 3.1.0
  26.  *
  27.  * @author Simone Tripodi
  28.  */
  29. public abstract class TypeReference<T> {

  30.   private final Type rawType;

  31.   protected TypeReference() {
  32.     rawType = getSuperclassTypeParameter(getClass());
  33.   }

  34.   Type getSuperclassTypeParameter(Class<?> clazz) {
  35.     Type genericSuperclass = clazz.getGenericSuperclass();
  36.     if (genericSuperclass instanceof Class) {
  37.       // try to climb up the hierarchy until meet something useful
  38.       if (TypeReference.class != genericSuperclass) {
  39.         return getSuperclassTypeParameter(clazz.getSuperclass());
  40.       }

  41.       throw new TypeException("'" + getClass() + "' extends TypeReference but misses the type parameter. "
  42.           + "Remove the extension or add a type parameter to it.");
  43.     }

  44.     Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
  45.     // TODO remove this when Reflector is fixed to return Types
  46.     if (rawType instanceof ParameterizedType) {
  47.       rawType = ((ParameterizedType) rawType).getRawType();
  48.     }

  49.     return rawType;
  50.   }

  51.   public final Type getRawType() {
  52.     return rawType;
  53.   }

  54.   @Override
  55.   public String toString() {
  56.     return rawType.toString();
  57.   }

  58. }