001    /*
002     * Created on Jan 24, 2009
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     *
013     * Copyright @2009 the original author or authors.
014     */
015    package org.fest.reflect.reference;
016    
017    import java.lang.reflect.ParameterizedType;
018    import java.lang.reflect.Type;
019    
020    import org.fest.reflect.exception.ReflectionError;
021    
022    /**
023     * Understands a references a generic type. Based on Neal Gafter's
024     * <code><a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html" target="_blank">TypeReference</a></code>.
025     * @param <T> the generic type in this reference.
026     *
027     * @author crazybob@google.com (Bob Lee)
028     * @author Alex Ruiz
029     *
030     * @since 1.1
031     */
032    public abstract class TypeRef<T> {
033    
034      private final Class<?> rawType;
035    
036      /**
037       * Creates a new </code>{@link TypeRef}</code>.
038       * @throws ReflectionError if the generic type of this reference is missing type parameter.
039       */
040      public TypeRef() {
041        Type superclass = getClass().getGenericSuperclass();
042        if (superclass instanceof Class<?>) throw new ReflectionError("Missing type parameter.");
043        Type type = ((ParameterizedType)superclass).getActualTypeArguments()[0];
044        rawType = type instanceof Class<?> ? (Class<?>)type : (Class<?>) ((ParameterizedType) type).getRawType();
045      }
046    
047      /**
048       * Returns the raw type of the generic type in this reference.
049       * @return the raw type of the generic type in this reference.
050       */
051      public final Class<?> rawType() {
052        return rawType;
053      }
054    }