1 /* 2 * Copyright (c) 2013, 2015, 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.annotation; 27 28 import java.lang.annotation.*; 29 import java.lang.reflect.*; 30 import java.util.ArrayList; 31 import java.util.Arrays; 32 import java.util.List; 33 import java.util.Map; 34 35 import static sun.reflect.annotation.TypeAnnotation.*; 36 37 public final class AnnotatedTypeFactory { 38 /** 39 * Create an AnnotatedType. 40 * 41 * @param type the type this AnnotatedType corresponds to 42 * @param currentLoc the location this AnnotatedType corresponds to 43 * @param actualTypeAnnos the type annotations this AnnotatedType has 44 * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget 45 * as the AnnotatedType being built 46 * @param decl the declaration having the type use this AnnotatedType 47 * corresponds to 48 */ 49 public static AnnotatedType buildAnnotatedType(Type type, 50 LocationInfo currentLoc, 51 TypeAnnotation[] actualTypeAnnos, 52 TypeAnnotation[] allOnSameTarget, 53 AnnotatedElement decl) { 54 if (type == null) { 55 return EMPTY_ANNOTATED_TYPE; 56 } 57 if (isArray(type)) 58 return new AnnotatedArrayTypeImpl(type, 59 currentLoc, 60 actualTypeAnnos, 61 allOnSameTarget, 62 decl); 63 if (type instanceof Class) { 64 return new AnnotatedTypeBaseImpl(type, 65 currentLoc, 66 actualTypeAnnos, 67 allOnSameTarget, 68 decl); 69 } else if (type instanceof TypeVariable) { 70 return new AnnotatedTypeVariableImpl((TypeVariable)type, 71 currentLoc, 72 actualTypeAnnos, 73 allOnSameTarget, 74 decl); 75 } else if (type instanceof ParameterizedType) { 76 return new AnnotatedParameterizedTypeImpl((ParameterizedType)type, 77 currentLoc, 78 actualTypeAnnos, 79 allOnSameTarget, 80 decl); 81 } else if (type instanceof WildcardType) { 82 return new AnnotatedWildcardTypeImpl((WildcardType) type, 83 currentLoc, 84 actualTypeAnnos, 85 allOnSameTarget, 86 decl); 87 } 88 throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen."); 89 } 90 91 public static LocationInfo nestingForType(Type type, LocationInfo addTo) { 92 if (isArray(type)) 93 return addTo; 94 if (type instanceof Class) { 95 Class<?> clz = (Class)type; 96 if (clz.getEnclosingClass() == null) 97 return addTo; 98 if (Modifier.isStatic(clz.getModifiers())) 99 return nestingForType(clz.getEnclosingClass(), addTo); 100 return nestingForType(clz.getEnclosingClass(), addTo.pushInner()); 101 } else if (type instanceof ParameterizedType) { 102 ParameterizedType t = (ParameterizedType)type; 103 if (t.getOwnerType() == null) 104 return addTo; 105 return nestingForType(t.getOwnerType(), addTo.pushInner()); 106 } 107 return addTo; 108 } 109 110 private static boolean isArray(Type t) { 111 if (t instanceof Class) { 112 Class<?> c = (Class)t; 113 if (c.isArray()) 114 return true; 115 } else if (t instanceof GenericArrayType) { 116 return true; 117 } 118 return false; 119 } 120 121 static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0]; 122 static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION, 123 EMPTY_TYPE_ANNOTATION_ARRAY, EMPTY_TYPE_ANNOTATION_ARRAY, null); 124 static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0]; 125 126 private static class AnnotatedTypeBaseImpl implements AnnotatedType { 127 private final Type type; 128 private final AnnotatedElement decl; 129 private final LocationInfo location; 130 private final TypeAnnotation[] allOnSameTargetTypeAnnotations; 131 private final Map<Class <? extends Annotation>, Annotation> annotations; 132 133 AnnotatedTypeBaseImpl(Type type, LocationInfo location, 134 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, 135 AnnotatedElement decl) { 136 this.type = type; 137 this.decl = decl; 138 this.location = location; 139 this.allOnSameTargetTypeAnnotations = allOnSameTargetTypeAnnotations; 140 this.annotations = TypeAnnotationParser.mapTypeAnnotations(location.filter(actualTypeAnnotations)); 141 } 142 143 // AnnotatedElement 144 @Override 145 public final Annotation[] getAnnotations() { 146 return getDeclaredAnnotations(); 147 } 148 149 @Override 150 public final <T extends Annotation> T getAnnotation(Class<T> annotation) { 151 return getDeclaredAnnotation(annotation); 152 } 153 154 @Override 155 public final <T extends Annotation> T[] getAnnotationsByType(Class<T> annotation) { 156 return getDeclaredAnnotationsByType(annotation); 157 } 158 159 @Override 160 public final Annotation[] getDeclaredAnnotations() { 161 return annotations.values().toArray(new Annotation[0]); 162 } 163 164 @Override 165 @SuppressWarnings("unchecked") 166 public final <T extends Annotation> T getDeclaredAnnotation(Class<T> annotation) { 167 return (T)annotations.get(annotation); 168 } 169 170 @Override 171 public final <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotation) { 172 return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotations, annotation); 173 } 174 175 // AnnotatedType 176 @Override 177 public final Type getType() { 178 return type; 179 } 180 181 @Override 182 public AnnotatedType getAnnotatedOwnerType() { 183 if (!(type instanceof Class<?>)) 184 throw new IllegalStateException("Can't compute owner"); 185 186 Class<?> inner = (Class<?>)type; 187 Class<?> owner = inner.getDeclaringClass(); 188 if (owner == null) // top-level, local or anonymous 189 return null; 190 if (inner.isPrimitive() || inner == Void.TYPE) 191 return null; 192 193 LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1)); 194 TypeAnnotation[]all = getTypeAnnotations(); 195 List<TypeAnnotation> l = new ArrayList<>(all.length); 196 197 for (TypeAnnotation t : all) 198 if (t.getLocationInfo().isSameLocationInfo(outerLoc)) 199 l.add(t); 200 201 return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl()); 202 203 } 204 205 // Implementation details 206 final LocationInfo getLocation() { 207 return location; 208 } 209 final TypeAnnotation[] getTypeAnnotations() { 210 return allOnSameTargetTypeAnnotations; 211 } 212 final AnnotatedElement getDecl() { 213 return decl; 214 } 215 } 216 217 private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType { 218 AnnotatedArrayTypeImpl(Type type, LocationInfo location, 219 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, 220 AnnotatedElement decl) { 221 super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); 222 } 223 224 @Override 225 public AnnotatedType getAnnotatedGenericComponentType() { 226 Type t = getComponentType(); 227 return AnnotatedTypeFactory.buildAnnotatedType(t, 228 nestingForType(t, getLocation().pushArray()), 229 getTypeAnnotations(), 230 getTypeAnnotations(), 231 getDecl()); 232 } 233 234 @Override 235 public AnnotatedType getAnnotatedOwnerType() { 236 return null; 237 } 238 239 private Type getComponentType() { 240 Type t = getType(); 241 if (t instanceof Class) { 242 Class<?> c = (Class)t; 243 return c.getComponentType(); 244 } 245 return ((GenericArrayType)t).getGenericComponentType(); 246 } 247 } 248 249 private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable { 250 AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location, 251 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, 252 AnnotatedElement decl) { 253 super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); 254 } 255 256 @Override 257 public AnnotatedType[] getAnnotatedBounds() { 258 return getTypeVariable().getAnnotatedBounds(); 259 } 260 261 @Override 262 public AnnotatedType getAnnotatedOwnerType() { 263 return null; 264 } 265 266 private TypeVariable<?> getTypeVariable() { 267 return (TypeVariable)getType(); 268 } 269 } 270 271 private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl 272 implements AnnotatedParameterizedType { 273 AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location, 274 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, 275 AnnotatedElement decl) { 276 super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); 277 } 278 279 @Override 280 public AnnotatedType[] getAnnotatedActualTypeArguments() { 281 Type[] arguments = getParameterizedType().getActualTypeArguments(); 282 AnnotatedType[] res = new AnnotatedType[arguments.length]; 283 Arrays.fill(res, EMPTY_ANNOTATED_TYPE); 284 int initialCapacity = getTypeAnnotations().length; 285 for (int i = 0; i < res.length; i++) { 286 List<TypeAnnotation> l = new ArrayList<>(initialCapacity); 287 LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i)); 288 for (TypeAnnotation t : getTypeAnnotations()) 289 if (t.getLocationInfo().isSameLocationInfo(newLoc)) 290 l.add(t); 291 res[i] = buildAnnotatedType(arguments[i], 292 newLoc, 293 l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), 294 getTypeAnnotations(), 295 getDecl()); 296 } 297 return res; 298 } 299 300 @Override 301 public AnnotatedType getAnnotatedOwnerType() { 302 Type owner = getParameterizedType().getOwnerType(); 303 if (owner == null) 304 return null; 305 LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1)); 306 TypeAnnotation[]all = getTypeAnnotations(); 307 List<TypeAnnotation> l = new ArrayList<>(all.length); 308 309 for (TypeAnnotation t : all) 310 if (t.getLocationInfo().isSameLocationInfo(outerLoc)) 311 l.add(t); 312 313 return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl()); 314 } 315 316 private ParameterizedType getParameterizedType() { 317 return (ParameterizedType)getType(); 318 } 319 } 320 321 private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType { 322 private final boolean hasUpperBounds; 323 AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location, 324 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations, 325 AnnotatedElement decl) { 326 super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl); 327 hasUpperBounds = (type.getLowerBounds().length == 0); 328 } 329 330 @Override 331 public AnnotatedType[] getAnnotatedUpperBounds() { 332 if (!hasUpperBounds()) { 333 return new AnnotatedType[] { buildAnnotatedType(Object.class, 334 LocationInfo.BASE_LOCATION, 335 EMPTY_TYPE_ANNOTATION_ARRAY, 336 EMPTY_TYPE_ANNOTATION_ARRAY, 337 null) 338 }; 339 } 340 return getAnnotatedBounds(getWildcardType().getUpperBounds()); 341 } 342 343 @Override 344 public AnnotatedType[] getAnnotatedLowerBounds() { 345 if (hasUpperBounds) 346 return new AnnotatedType[0]; 347 return getAnnotatedBounds(getWildcardType().getLowerBounds()); 348 } 349 350 @Override 351 public AnnotatedType getAnnotatedOwnerType() { 352 return null; 353 } 354 355 private AnnotatedType[] getAnnotatedBounds(Type[] bounds) { 356 AnnotatedType[] res = new AnnotatedType[bounds.length]; 357 Arrays.fill(res, EMPTY_ANNOTATED_TYPE); 358 int initialCapacity = getTypeAnnotations().length; 359 for (int i = 0; i < res.length; i++) { 360 LocationInfo newLoc = nestingForType(bounds[i], getLocation().pushWildcard()); 361 List<TypeAnnotation> l = new ArrayList<>(initialCapacity); 362 for (TypeAnnotation t : getTypeAnnotations()) 363 if (t.getLocationInfo().isSameLocationInfo(newLoc)) 364 l.add(t); 365 res[i] = buildAnnotatedType(bounds[i], 366 newLoc, 367 l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), 368 getTypeAnnotations(), 369 getDecl()); 370 } 371 return res; 372 } 373 374 private WildcardType getWildcardType() { 375 return (WildcardType)getType(); 376 } 377 378 private boolean hasUpperBounds() { 379 return hasUpperBounds; 380 } 381 } 382 }