1 /*
   2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.reflect.generics.reflectiveObjects;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.AnnotatedType;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.GenericDeclaration;
  32 import java.lang.reflect.Type;
  33 import java.lang.reflect.TypeVariable;
  34 import java.util.LinkedHashMap;
  35 import java.util.Map;
  36 import java.util.Objects;
  37 import sun.reflect.annotation.AnnotationSupport;
  38 import sun.reflect.annotation.TypeAnnotationParser;
  39 import sun.reflect.annotation.AnnotationType;
  40 import sun.reflect.generics.factory.GenericsFactory;
  41 import sun.reflect.generics.tree.FieldTypeSignature;
  42 import sun.reflect.generics.visitor.Reifier;
  43 
  44 /**
  45  * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
  46  * for core reflection.
  47  */
  48 public class TypeVariableImpl<D extends GenericDeclaration>
  49     extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
  50     D genericDeclaration;
  51     private String name;
  52     // upper bounds - evaluated lazily
  53     private Type[] bounds;
  54 
  55     // The ASTs for the bounds. We are required to evaluate the bounds
  56     // lazily, so we store these at least until we are first asked
  57     // for the bounds. This also neatly solves the
  58     // problem with F-bounds - you can't reify them before the formal
  59     // is defined.
  60     private FieldTypeSignature[] boundASTs;
  61 
  62     // constructor is private to enforce access through static factory
  63     private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
  64                              GenericsFactory f) {
  65         super(f);
  66         genericDeclaration = decl;
  67         name = n;
  68         boundASTs = bs;
  69     }
  70 
  71     // Accessors
  72 
  73     // accessor for ASTs for bounds. Must not be called after
  74     // bounds have been evaluated, because we might throw the ASTs
  75     // away (but that is not thread-safe, is it?)
  76     private FieldTypeSignature[] getBoundASTs() {
  77         // check that bounds were not evaluated yet
  78         assert(bounds == null);
  79         return boundASTs;
  80     }
  81 
  82     /**
  83      * Factory method.
  84      * @param decl - the reflective object that declared the type variable
  85      * that this method should create
  86      * @param name - the name of the type variable to be returned
  87      * @param bs - an array of ASTs representing the bounds for the type
  88      * variable to be created
  89      * @param f - a factory that can be used to manufacture reflective
  90      * objects that represent the bounds of this type variable
  91      * @return A type variable with name, bounds, declaration and factory
  92      * specified
  93      */
  94     public static <T extends GenericDeclaration>
  95                              TypeVariableImpl<T> make(T decl, String name,
  96                                                       FieldTypeSignature[] bs,
  97                                                       GenericsFactory f) {
  98         return new TypeVariableImpl<T>(decl, name, bs, f);
  99     }
 100 
 101 
 102     /**
 103      * Returns an array of <tt>Type</tt> objects representing the
 104      * upper bound(s) of this type variable.  Note that if no upper bound is
 105      * explicitly declared, the upper bound is <tt>Object</tt>.
 106      *
 107      * <p>For each upper bound B:
 108      * <ul>
 109      *  <li>if B is a parameterized type or a type variable, it is created,
 110      *  (see {@link #ParameterizedType} for the details of the creation
 111      *  process for parameterized types).
 112      *  <li>Otherwise, B is resolved.
 113      * </ul>
 114      *
 115      * @throws <tt>TypeNotPresentException</tt>  if any of the
 116      *     bounds refers to a non-existent type declaration
 117      * @throws <tt>MalformedParameterizedTypeException</tt> if any of the
 118      *     bounds refer to a parameterized type that cannot be instantiated
 119      *     for any reason
 120      * @return an array of Types representing the upper bound(s) of this
 121      *     type variable
 122     */
 123     public Type[] getBounds() {
 124         // lazily initialize bounds if necessary
 125         if (bounds == null) {
 126             FieldTypeSignature[] fts = getBoundASTs(); // get AST
 127             // allocate result array; note that
 128             // keeping ts and bounds separate helps with threads
 129             Type[] ts = new Type[fts.length];
 130             // iterate over bound trees, reifying each in turn
 131             for ( int j = 0; j  < fts.length; j++) {
 132                 Reifier r = getReifier();
 133                 fts[j].accept(r);
 134                 ts[j] = r.getResult();
 135             }
 136             // cache result
 137             bounds = ts;
 138             // could throw away bound ASTs here; thread safety?
 139         }
 140         return bounds.clone(); // return cached bounds
 141     }
 142 
 143     /**
 144      * Returns the <tt>GenericDeclaration</tt>  object representing the
 145      * generic declaration that declared this type variable.
 146      *
 147      * @return the generic declaration that declared this type variable.
 148      *
 149      * @since 1.5
 150      */
 151     public D getGenericDeclaration(){
 152         return genericDeclaration;
 153     }
 154 
 155 
 156     /**
 157      * Returns the name of this type variable, as it occurs in the source code.
 158      *
 159      * @return the name of this type variable, as it appears in the source code
 160      */
 161     public String getName()   { return name; }
 162 
 163     public String toString() {return getName();}
 164 
 165     @Override
 166     public boolean equals(Object o) {
 167         if (o instanceof TypeVariable) {
 168             TypeVariable<?> that = (TypeVariable<?>) o;
 169 
 170             GenericDeclaration thatDecl = that.getGenericDeclaration();
 171             String thatName = that.getName();
 172 
 173             return Objects.equals(genericDeclaration, thatDecl) &&
 174                 Objects.equals(name, thatName);
 175 
 176         } else
 177             return false;
 178     }
 179 
 180     @Override
 181     public int hashCode() {
 182         return genericDeclaration.hashCode() ^ name.hashCode();
 183     }
 184 
 185     // Implementations of AnnotatedElement methods.
 186     @SuppressWarnings("unchecked")
 187     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
 188         Objects.requireNonNull(annotationClass);
 189         // T is an Annotation type, the return value of get will be an annotation
 190         return (T)mapAnnotations(getAnnotations()).get(annotationClass);
 191     }
 192 
 193     public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
 194         Objects.requireNonNull(annotationClass);
 195         return getAnnotation(annotationClass);
 196     }
 197 
 198     @Override
 199     public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
 200         Objects.requireNonNull(annotationClass);
 201         return AnnotationSupport.getMultipleAnnotations(mapAnnotations(getAnnotations()), annotationClass);
 202     }
 203 
 204     @Override
 205     public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
 206         Objects.requireNonNull(annotationClass);
 207         return getAnnotationsByType(annotationClass);
 208     }
 209 
 210     public Annotation[] getAnnotations() {
 211         int myIndex = typeVarIndex();
 212         if (myIndex < 0)
 213             throw new AssertionError("Index must be non-negative.");
 214         return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex);
 215     }
 216 
 217     public Annotation[] getDeclaredAnnotations() {
 218         return getAnnotations();
 219     }
 220 
 221     public AnnotatedType[] getAnnotatedBounds() {
 222         return TypeAnnotationParser.parseAnnotatedBounds(getBounds(),
 223                                                          getGenericDeclaration(),
 224                                                          typeVarIndex());
 225     }
 226 
 227     private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
 228 
 229     // Helpers for annotation methods
 230     private int typeVarIndex() {
 231         TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters();
 232         int i = -1;
 233         for (TypeVariable<?> v : tVars) {
 234             i++;
 235             if (equals(v))
 236                 return i;
 237         }
 238         return -1;
 239     }
 240 
 241     private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) {
 242         Map<Class<? extends Annotation>, Annotation> result =
 243             new LinkedHashMap<>();
 244         for (Annotation a : annos) {
 245             Class<? extends Annotation> klass = a.annotationType();
 246             AnnotationType type = AnnotationType.getInstance(klass);
 247             if (type.retention() == RetentionPolicy.RUNTIME)
 248                 if (result.put(klass, a) != null)
 249                     throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
 250         }
 251         return result;
 252     }
 253 }