< prev index next >

src/java.base/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java

Print this page




  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) {


 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


 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())


 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                 };


 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 }


  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 import java.util.Objects;
  35 import java.util.StringJoiner;
  36 
  37 import static sun.reflect.annotation.TypeAnnotation.*;
  38 
  39 public final class AnnotatedTypeFactory {
  40     /**
  41      * Create an AnnotatedType.
  42      *
  43      * @param type the type this AnnotatedType corresponds to
  44      * @param currentLoc the location this AnnotatedType corresponds to
  45      * @param actualTypeAnnos the type annotations this AnnotatedType has
  46      * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
  47      *                          as the AnnotatedType being built
  48      * @param decl the declaration having the type use this AnnotatedType
  49      *                          corresponds to
  50      */
  51     public static AnnotatedType buildAnnotatedType(Type type,
  52             LocationInfo currentLoc,
  53             TypeAnnotation[] actualTypeAnnos,
  54             TypeAnnotation[] allOnSameTarget,
  55             AnnotatedElement decl) {


 187 
 188             Class<?> inner = (Class<?>)type;
 189             Class<?> owner = inner.getDeclaringClass();
 190             if (owner == null) // top-level, local or anonymous
 191                 return null;
 192             if (inner.isPrimitive() || inner == Void.TYPE)
 193                 return null;
 194 
 195             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 196             TypeAnnotation[]all = getTypeAnnotations();
 197             List<TypeAnnotation> l = new ArrayList<>(all.length);
 198 
 199             for (TypeAnnotation t : all)
 200                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 201                     l.add(t);
 202 
 203             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 204 
 205         }
 206 
 207         @Override
 208         public String toString() {
 209             // Reusable toString implementation, but needs to be
 210             // specialized for quirks of arrays.
 211             return annotationsToString(getAnnotations(), false) + type.toString();
 212         }
 213 
 214         protected String annotationsToString(Annotation[] annotations, boolean leadingSpace) {
 215             StringJoiner sj = new StringJoiner(" ");
 216             if (annotations != null && annotations.length > 0) {
 217                 if (leadingSpace) {
 218                     sj.add(""); // Add a space
 219                 }
 220 
 221                 for (Annotation annotation : annotations) {
 222                     sj.add(annotation.toString());
 223                 }
 224 
 225                 if (!leadingSpace) {
 226                     sj.add("");
 227                 }
 228             }
 229             return sj.toString();
 230         }
 231 
 232         protected boolean equalsTypeAndAnnotations(AnnotatedType that) {
 233             return getType().equals(that.getType()) &&
 234                 // Treat ordering of annotations as significant
 235                 Arrays.equals(getAnnotations(), that.getAnnotations()) &&
 236                 Objects.equals(getAnnotatedOwnerType(), that.getAnnotatedOwnerType());
 237         }
 238 
 239         int baseHashCode() {
 240             return type.hashCode() ^
 241                 // Acceptable to use Objects.hash rather than
 242                 // Arrays.deepHashCode since the elements of the array
 243                 // are not themselves arrays.
 244                 Objects.hash((Object[])getAnnotations());
 245         }
 246 
 247         @Override
 248         public boolean equals(Object o) {
 249             if (o instanceof AnnotatedType &&
 250                 !(o instanceof AnnotatedArrayType) &&
 251                 !(o instanceof AnnotatedTypeVariable) &&
 252                 !(o instanceof AnnotatedParameterizedType) &&
 253                 !(o instanceof AnnotatedWildcardType)) {
 254                 AnnotatedType that = (AnnotatedType) o;
 255                 return equalsTypeAndAnnotations(that);
 256             } else {
 257                 return false;
 258             }
 259         }
 260 
 261         @Override
 262         public int hashCode() {
 263             return baseHashCode();
 264         }
 265 
 266         // Implementation details
 267         final LocationInfo getLocation() {
 268             return location;
 269         }
 270         final TypeAnnotation[] getTypeAnnotations() {
 271             return allOnSameTargetTypeAnnotations;
 272         }
 273         final AnnotatedElement getDecl() {
 274             return decl;
 275         }
 276     }
 277 
 278     private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
 279         AnnotatedArrayTypeImpl(Type type, LocationInfo location,
 280                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 281                 AnnotatedElement decl) {
 282             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 283         }
 284 
 285         @Override


 288             return AnnotatedTypeFactory.buildAnnotatedType(t,
 289                     nestingForType(t, getLocation().pushArray()),
 290                     getTypeAnnotations(),
 291                     getTypeAnnotations(),
 292                     getDecl());
 293         }
 294 
 295         @Override
 296         public AnnotatedType getAnnotatedOwnerType() {
 297             return null;
 298         }
 299 
 300         private Type getComponentType() {
 301             Type t = getType();
 302             if (t instanceof Class) {
 303                 Class<?> c = (Class)t;
 304                 return c.getComponentType();
 305             }
 306             return ((GenericArrayType)t).getGenericComponentType();
 307         }
 308 
 309         @Override
 310         public String toString() {
 311             // To annotate the full type of an array, the annotations
 312             // are placed between the type and the brackets. For
 313             // example, to annotate an array of Strings, the syntax used is
 314             //
 315             // String @TypeAnnotation []
 316             //
 317             // and *not*
 318             //
 319             // @TypeAnnotation String[].
 320             //
 321             // The toString output should strive to be reusable in
 322             // source code. Therefore, the general logic of putting
 323             // the annotations before a textual representation of the
 324             // type need to be overridden for arrays.
 325             StringBuilder sb = new StringBuilder();
 326 
 327             AnnotatedType componentType = this;
 328             while (componentType instanceof AnnotatedArrayType) {
 329                 AnnotatedArrayType annotatedArrayType = (AnnotatedArrayType) componentType;
 330                 sb.append(annotationsToString(annotatedArrayType.getAnnotations(), true) + "[]");
 331                 componentType = annotatedArrayType.getAnnotatedGenericComponentType();
 332             }
 333 
 334             sb.insert(0, componentType.toString());
 335             return sb.toString();
 336         }
 337 
 338         @Override
 339         public boolean equals(Object o) {
 340             if (o instanceof AnnotatedArrayType) {
 341                 AnnotatedArrayType that = (AnnotatedArrayType) o;
 342                 return equalsTypeAndAnnotations(that) &&
 343                     Objects.equals(getAnnotatedGenericComponentType(),
 344                                    that.getAnnotatedGenericComponentType());
 345             } else {
 346                 return false;
 347             }
 348         }
 349 
 350         @Override
 351         public int hashCode() {
 352             return baseHashCode() ^ getAnnotatedGenericComponentType().hashCode();
 353         }
 354     }
 355 
 356     private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
 357         AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
 358                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 359                 AnnotatedElement decl) {
 360             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 361         }
 362 
 363         @Override
 364         public AnnotatedType[] getAnnotatedBounds() {
 365             return getTypeVariable().getAnnotatedBounds();
 366         }
 367 
 368         @Override
 369         public AnnotatedType getAnnotatedOwnerType() {
 370             return null;
 371         }
 372 
 373         private TypeVariable<?> getTypeVariable() {
 374             return (TypeVariable)getType();
 375         }
 376 
 377         @Override
 378         public boolean equals(Object o) {
 379             if (o instanceof AnnotatedTypeVariable) {
 380                 AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
 381                 return equalsTypeAndAnnotations(that) &&
 382                     Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
 383             } else {
 384                 return false;
 385             }
 386         }
 387 
 388         @Override
 389         public int hashCode() {
 390             return baseHashCode() ^
 391                 Objects.hash((Object[])getAnnotatedBounds());
 392         }
 393     }
 394 
 395     private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
 396             implements AnnotatedParameterizedType {
 397         AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
 398                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 399                 AnnotatedElement decl) {
 400             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 401         }
 402 
 403         @Override
 404         public AnnotatedType[] getAnnotatedActualTypeArguments() {
 405             Type[] arguments = getParameterizedType().getActualTypeArguments();
 406             AnnotatedType[] res = new AnnotatedType[arguments.length];
 407             Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
 408             int initialCapacity = getTypeAnnotations().length;
 409             for (int i = 0; i < res.length; i++) {
 410                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 411                 LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i));
 412                 for (TypeAnnotation t : getTypeAnnotations())


 423 
 424         @Override
 425         public AnnotatedType getAnnotatedOwnerType() {
 426             Type owner = getParameterizedType().getOwnerType();
 427             if (owner == null)
 428                 return null;
 429             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 430             TypeAnnotation[]all = getTypeAnnotations();
 431             List<TypeAnnotation> l = new ArrayList<>(all.length);
 432 
 433             for (TypeAnnotation t : all)
 434                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 435                     l.add(t);
 436 
 437             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 438         }
 439 
 440         private ParameterizedType getParameterizedType() {
 441             return (ParameterizedType)getType();
 442         }
 443 
 444         @Override
 445         public boolean equals(Object o) {
 446             if (o instanceof AnnotatedParameterizedType) {
 447                 AnnotatedParameterizedType that = (AnnotatedParameterizedType) o;
 448                 return equalsTypeAndAnnotations(that) &&
 449                     Arrays.equals(getAnnotatedActualTypeArguments(), that.getAnnotatedActualTypeArguments());
 450             } else {
 451                 return false;
 452             }
 453         }
 454 
 455         @Override
 456         public int hashCode() {
 457             return baseHashCode() ^
 458                 Objects.hash((Object[])getAnnotatedActualTypeArguments());
 459         }
 460     }
 461 
 462     private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
 463         private final boolean hasUpperBounds;
 464         AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
 465                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 466                 AnnotatedElement decl) {
 467             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 468             hasUpperBounds = (type.getLowerBounds().length == 0);
 469         }
 470 
 471         @Override
 472         public AnnotatedType[] getAnnotatedUpperBounds() {
 473             if (!hasUpperBounds()) {
 474                 return new AnnotatedType[] { buildAnnotatedType(Object.class,
 475                         LocationInfo.BASE_LOCATION,
 476                         EMPTY_TYPE_ANNOTATION_ARRAY,
 477                         EMPTY_TYPE_ANNOTATION_ARRAY,
 478                         null)
 479                 };


 501                 LocationInfo newLoc = nestingForType(bounds[i], getLocation().pushWildcard());
 502                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 503                 for (TypeAnnotation t : getTypeAnnotations())
 504                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
 505                         l.add(t);
 506                 res[i] = buildAnnotatedType(bounds[i],
 507                         newLoc,
 508                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 509                         getTypeAnnotations(),
 510                         getDecl());
 511             }
 512             return res;
 513         }
 514 
 515         private WildcardType getWildcardType() {
 516             return (WildcardType)getType();
 517         }
 518 
 519         private boolean hasUpperBounds() {
 520             return hasUpperBounds;
 521         }
 522 
 523         @Override
 524         public boolean equals(Object o) {
 525             if (o instanceof AnnotatedWildcardType) {
 526                 AnnotatedWildcardType that = (AnnotatedWildcardType) o;
 527                 return equalsTypeAndAnnotations(that) &&
 528                     // Treats ordering as significant
 529                     Arrays.equals(getAnnotatedLowerBounds(), that.getAnnotatedLowerBounds()) &&
 530                     // Treats ordering as significant
 531                     Arrays.equals(getAnnotatedUpperBounds(), that.getAnnotatedUpperBounds());
 532             } else {
 533                 return false;
 534             }
 535         }
 536 
 537         @Override
 538         public int hashCode() {
 539             return baseHashCode() ^
 540                 Objects.hash((Object[])getAnnotatedLowerBounds()) ^
 541                 Objects.hash((Object[])getAnnotatedUpperBounds());
 542         }
 543     }
 544 }
< prev index next >