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.Constructor; 32 import java.lang.reflect.GenericDeclaration; 33 import java.lang.reflect.Member; 34 import java.lang.reflect.Method; 35 import java.lang.reflect.Type; 36 import java.lang.reflect.TypeVariable; 37 import java.util.LinkedHashMap; 38 import java.util.Map; 39 import java.util.Objects; 40 import sun.reflect.annotation.AnnotationSupport; 41 import sun.reflect.annotation.TypeAnnotationParser; 42 import sun.reflect.annotation.AnnotationType; 43 import sun.reflect.generics.factory.GenericsFactory; 44 import sun.reflect.generics.tree.FieldTypeSignature; 45 import sun.reflect.generics.visitor.Reifier; 46 import sun.reflect.misc.ReflectUtil; 47 48 /** 49 * Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface 50 * for core reflection. 51 */ 52 public class TypeVariableImpl<D extends GenericDeclaration> 53 extends LazyReflectiveObjectGenerator implements TypeVariable<D> { 54 D genericDeclaration; 55 private String name; 56 // upper bounds - evaluated lazily 57 private Type[] bounds; 58 59 // The ASTs for the bounds. We are required to evaluate the bounds 60 // lazily, so we store these at least until we are first asked 61 // for the bounds. This also neatly solves the 62 // problem with F-bounds - you can't reify them before the formal 63 // is defined. 64 private FieldTypeSignature[] boundASTs; 65 66 // constructor is private to enforce access through static factory 67 private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs, 68 GenericsFactory f) { 69 super(f); 70 genericDeclaration = decl; 71 name = n; 72 boundASTs = bs; 73 } 74 75 // Accessors 76 77 // accessor for ASTs for bounds. Must not be called after 78 // bounds have been evaluated, because we might throw the ASTs 79 // away (but that is not thread-safe, is it?) 80 private FieldTypeSignature[] getBoundASTs() { 81 // check that bounds were not evaluated yet 82 assert(bounds == null); 83 return boundASTs; 84 } 85 86 /** 87 * Factory method. 88 * @param decl - the reflective object that declared the type variable 89 * that this method should create 90 * @param name - the name of the type variable to be returned 91 * @param bs - an array of ASTs representing the bounds for the type 92 * variable to be created 93 * @param f - a factory that can be used to manufacture reflective 94 * objects that represent the bounds of this type variable 95 * @return A type variable with name, bounds, declaration and factory 96 * specified 97 */ 98 public static <T extends GenericDeclaration> 99 TypeVariableImpl<T> make(T decl, String name, 100 FieldTypeSignature[] bs, 101 GenericsFactory f) { 102 103 if (!((decl instanceof Class) || 104 (decl instanceof Method) || 105 (decl instanceof Constructor))) { 106 throw new AssertionError("Unexpected kind of GenericDeclaration" + 107 decl.getClass().toString()); 108 } 109 return new TypeVariableImpl<T>(decl, name, bs, f); 110 } 111 112 113 /** 114 * Returns an array of <tt>Type</tt> objects representing the 115 * upper bound(s) of this type variable. Note that if no upper bound is 116 * explicitly declared, the upper bound is <tt>Object</tt>. 117 * 118 * <p>For each upper bound B: 119 * <ul> 120 * <li>if B is a parameterized type or a type variable, it is created, 121 * (see {@link #ParameterizedType} for the details of the creation 122 * process for parameterized types). 123 * <li>Otherwise, B is resolved. 124 * </ul> 125 * 126 * @throws <tt>TypeNotPresentException</tt> if any of the 127 * bounds refers to a non-existent type declaration 128 * @throws <tt>MalformedParameterizedTypeException</tt> if any of the 129 * bounds refer to a parameterized type that cannot be instantiated 130 * for any reason 131 * @return an array of Types representing the upper bound(s) of this 132 * type variable 133 */ 134 public Type[] getBounds() { 135 // lazily initialize bounds if necessary 136 if (bounds == null) { 137 FieldTypeSignature[] fts = getBoundASTs(); // get AST 138 // allocate result array; note that 139 // keeping ts and bounds separate helps with threads 140 Type[] ts = new Type[fts.length]; 141 // iterate over bound trees, reifying each in turn 142 for ( int j = 0; j < fts.length; j++) { 143 Reifier r = getReifier(); 144 fts[j].accept(r); 145 ts[j] = r.getResult(); 146 } 147 // cache result 148 bounds = ts; 149 // could throw away bound ASTs here; thread safety? 150 } 151 return bounds.clone(); // return cached bounds 152 } 153 154 /** 155 * Returns the <tt>GenericDeclaration</tt> object representing the 156 * generic declaration that declared this type variable. 157 * 158 * @return the generic declaration that declared this type variable. 159 * 160 * @since 1.5 161 */ 162 public D getGenericDeclaration(){ 163 if (genericDeclaration instanceof Class) 164 ReflectUtil.checkPackageAccess((Class)genericDeclaration); 165 else if ((genericDeclaration instanceof Method) || 166 (genericDeclaration instanceof Constructor)) 167 ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration); 168 else 169 throw new AssertionError("Unexpected kind of GenericDeclaration"); 170 return genericDeclaration; 171 } 172 173 174 /** 175 * Returns the name of this type variable, as it occurs in the source code. 176 * 177 * @return the name of this type variable, as it appears in the source code 178 */ 179 public String getName() { return name; } 180 181 public String toString() {return getName();} 182 183 @Override 184 public boolean equals(Object o) { 185 if (o instanceof TypeVariable && 186 o.getClass() == TypeVariableImpl.class) { 187 TypeVariable<?> that = (TypeVariable<?>) o; 188 189 GenericDeclaration thatDecl = that.getGenericDeclaration(); 190 String thatName = that.getName(); 191 192 return Objects.equals(genericDeclaration, thatDecl) && 193 Objects.equals(name, thatName); 194 195 } else 196 return false; 197 } 198 199 @Override 200 public int hashCode() { 201 return genericDeclaration.hashCode() ^ name.hashCode(); 202 } 203 204 // Implementations of AnnotatedElement methods. 205 @SuppressWarnings("unchecked") 206 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 207 Objects.requireNonNull(annotationClass); 208 // T is an Annotation type, the return value of get will be an annotation 209 return (T)mapAnnotations(getAnnotations()).get(annotationClass); 210 } 211 212 public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) { 213 Objects.requireNonNull(annotationClass); 214 return getAnnotation(annotationClass); 215 } 216 217 @Override 218 public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { 219 Objects.requireNonNull(annotationClass); 220 return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass); 221 } 222 223 @Override 224 public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 225 Objects.requireNonNull(annotationClass); 226 return getAnnotationsByType(annotationClass); 227 } 228 229 public Annotation[] getAnnotations() { 230 int myIndex = typeVarIndex(); 231 if (myIndex < 0) 232 throw new AssertionError("Index must be non-negative."); 233 return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex); 234 } 235 236 public Annotation[] getDeclaredAnnotations() { 237 return getAnnotations(); 238 } 239 240 public AnnotatedType[] getAnnotatedBounds() { 241 return TypeAnnotationParser.parseAnnotatedBounds(getBounds(), 242 getGenericDeclaration(), 243 typeVarIndex()); 244 } 245 246 private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; 247 248 // Helpers for annotation methods 249 private int typeVarIndex() { 250 TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters(); 251 int i = -1; 252 for (TypeVariable<?> v : tVars) { 253 i++; 254 if (equals(v)) 255 return i; 256 } 257 return -1; 258 } 259 260 private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) { 261 Map<Class<? extends Annotation>, Annotation> result = 262 new LinkedHashMap<>(); 263 for (Annotation a : annos) { 264 Class<? extends Annotation> klass = a.annotationType(); 265 AnnotationType type = AnnotationType.getInstance(klass); 266 if (type.retention() == RetentionPolicy.RUNTIME) 267 if (result.put(klass, a) != null) 268 throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a); 269 } 270 return result; 271 } 272 }