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


 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             Annotation[] annotations = getAnnotations();
 210             StringJoiner sj = new StringJoiner("\n");
 211             if (annotations != null) {
 212                 for (Annotation annotation : annotations) {
 213                     sj.add(annotation.toString());
 214                 }
 215                 sj.add(""); // Add a newline
 216             }
 217             return sj.toString() + type.toString();
 218         }
 219 
 220         /*
 221          * Testing notes: see if type.toString() is a postfix of AnnotatedType.toString()
 222 
 223          * For the annotations, for multiple annotations, compare with
 224          * a runtime construction since the order of annotations from
 225          * getAnnotations is not specified.
 226          */
 227 
 228         boolean equalsTypeAndAnnotations(AnnotatedType that) {
 229             return getType().equals(that.getType()) &&
 230                 // Treat ordering of annotations as significant
 231                 Arrays.equals(getAnnotations(), that.getAnnotations()) &&
 232                 Objects.equals(getAnnotatedOwnerType(), that.getAnnotatedOwnerType());
 233         }
 234 
 235         int baseHashCode() {
 236             return type.hashCode() ^
 237                 // Acceptable to use Objects.hash rather than
 238                 // Arrays.deepHashCode since the elements of the array
 239                 // are not themselves arrays.
 240                 Objects.hash((Object[])getAnnotations());
 241         }
 242 
 243         // Implementation details
 244         final LocationInfo getLocation() {
 245             return location;
 246         }
 247         final TypeAnnotation[] getTypeAnnotations() {
 248             return allOnSameTargetTypeAnnotations;
 249         }
 250         final AnnotatedElement getDecl() {
 251             return decl;
 252         }
 253     }
 254 
 255     private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
 256         AnnotatedArrayTypeImpl(Type type, LocationInfo location,
 257                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 258                 AnnotatedElement decl) {
 259             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 260         }
 261 
 262         @Override


 265             return AnnotatedTypeFactory.buildAnnotatedType(t,
 266                     nestingForType(t, getLocation().pushArray()),
 267                     getTypeAnnotations(),
 268                     getTypeAnnotations(),
 269                     getDecl());
 270         }
 271 
 272         @Override
 273         public AnnotatedType getAnnotatedOwnerType() {
 274             return null;
 275         }
 276 
 277         private Type getComponentType() {
 278             Type t = getType();
 279             if (t instanceof Class) {
 280                 Class<?> c = (Class)t;
 281                 return c.getComponentType();
 282             }
 283             return ((GenericArrayType)t).getGenericComponentType();
 284         }
 285 
 286         @Override
 287         public boolean equals(Object o) {
 288             if (o instanceof AnnotatedArrayType) {
 289                 AnnotatedArrayType that = (AnnotatedArrayType) o;
 290                 return equalsTypeAndAnnotations(that) &&
 291                     Objects.equals(getAnnotatedGenericComponentType(),
 292                                    that.getAnnotatedGenericComponentType());
 293             } else {
 294                 return false;
 295             }
 296         }
 297 
 298         @Override
 299         public int hashCode() {
 300             return baseHashCode() ^ getAnnotatedGenericComponentType().hashCode();
 301         }
 302     }
 303 
 304     private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
 305         AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
 306                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 307                 AnnotatedElement decl) {
 308             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 309         }
 310 
 311         @Override
 312         public AnnotatedType[] getAnnotatedBounds() {
 313             return getTypeVariable().getAnnotatedBounds();
 314         }
 315 
 316         @Override
 317         public AnnotatedType getAnnotatedOwnerType() {
 318             return null;
 319         }
 320 
 321         private TypeVariable<?> getTypeVariable() {
 322             return (TypeVariable)getType();
 323         }
 324 
 325         @Override
 326         public boolean equals(Object o) {
 327             if (o instanceof AnnotatedTypeVariable) {
 328                 AnnotatedTypeVariable that = (AnnotatedTypeVariable) o;
 329                 return equalsTypeAndAnnotations(that) &&
 330                     Arrays.equals(getAnnotatedBounds(), that.getAnnotatedBounds());
 331             } else {
 332                 return false;
 333             }
 334         }
 335 
 336         @Override
 337         public int hashCode() {
 338             return baseHashCode() ^
 339                 Objects.hash((Object[])getAnnotatedBounds());
 340         }
 341     }
 342 
 343     private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
 344             implements AnnotatedParameterizedType {
 345         AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
 346                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 347                 AnnotatedElement decl) {
 348             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 349         }
 350 
 351         @Override
 352         public AnnotatedType[] getAnnotatedActualTypeArguments() {
 353             Type[] arguments = getParameterizedType().getActualTypeArguments();
 354             AnnotatedType[] res = new AnnotatedType[arguments.length];
 355             Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
 356             int initialCapacity = getTypeAnnotations().length;
 357             for (int i = 0; i < res.length; i++) {
 358                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 359                 LocationInfo newLoc = nestingForType(arguments[i], getLocation().pushTypeArg((byte)i));
 360                 for (TypeAnnotation t : getTypeAnnotations())


 371 
 372         @Override
 373         public AnnotatedType getAnnotatedOwnerType() {
 374             Type owner = getParameterizedType().getOwnerType();
 375             if (owner == null)
 376                 return null;
 377             LocationInfo outerLoc = nestingForType(owner, getLocation().popAllLocations((byte)1));
 378             TypeAnnotation[]all = getTypeAnnotations();
 379             List<TypeAnnotation> l = new ArrayList<>(all.length);
 380 
 381             for (TypeAnnotation t : all)
 382                 if (t.getLocationInfo().isSameLocationInfo(outerLoc))
 383                     l.add(t);
 384 
 385             return buildAnnotatedType(owner, outerLoc, l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), all, getDecl());
 386         }
 387 
 388         private ParameterizedType getParameterizedType() {
 389             return (ParameterizedType)getType();
 390         }
 391 
 392         @Override
 393         public boolean equals(Object o) {
 394             if (o instanceof AnnotatedParameterizedType) {
 395                 AnnotatedParameterizedType that = (AnnotatedParameterizedType) o;
 396                 return equalsTypeAndAnnotations(that) &&
 397                     Arrays.equals(getAnnotatedActualTypeArguments(), that.getAnnotatedActualTypeArguments());
 398             } else {
 399                 return false;
 400             }
 401         }
 402 
 403         @Override
 404         public int hashCode() {
 405             return baseHashCode() ^
 406                 Objects.hash((Object[])getAnnotatedActualTypeArguments());
 407         }
 408     }
 409 
 410     private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
 411         private final boolean hasUpperBounds;
 412         AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
 413                 TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
 414                 AnnotatedElement decl) {
 415             super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
 416             hasUpperBounds = (type.getLowerBounds().length == 0);
 417         }
 418 
 419         @Override
 420         public AnnotatedType[] getAnnotatedUpperBounds() {
 421             if (!hasUpperBounds()) {
 422                 return new AnnotatedType[] { buildAnnotatedType(Object.class,
 423                         LocationInfo.BASE_LOCATION,
 424                         EMPTY_TYPE_ANNOTATION_ARRAY,
 425                         EMPTY_TYPE_ANNOTATION_ARRAY,
 426                         null)
 427                 };


 450                 List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
 451                 for (TypeAnnotation t : getTypeAnnotations())
 452                     if (t.getLocationInfo().isSameLocationInfo(newLoc))
 453                         l.add(t);
 454                 res[i] = buildAnnotatedType(bounds[i],
 455                         newLoc,
 456                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 457                         getTypeAnnotations(),
 458                         getDecl());
 459             }
 460             return res;
 461         }
 462 
 463         private WildcardType getWildcardType() {
 464             return (WildcardType)getType();
 465         }
 466 
 467         private boolean hasUpperBounds() {
 468             return hasUpperBounds;
 469         }
 470 
 471         @Override
 472         public boolean equals(Object o) {
 473             if (o instanceof AnnotatedWildcardType) {
 474                 AnnotatedWildcardType that = (AnnotatedWildcardType) o;
 475                 return equalsTypeAndAnnotations(that) &&
 476                     // Treats ordering as significant
 477                     Arrays.equals(getAnnotatedLowerBounds(), that.getAnnotatedLowerBounds()) &&
 478                     // Treats ordering as significant
 479                     Arrays.equals(getAnnotatedUpperBounds(), that.getAnnotatedUpperBounds());
 480             } else {
 481                 return false;
 482             }
 483         }
 484 
 485         @Override
 486         public int hashCode() {
 487             return baseHashCode() ^
 488                 Objects.hash((Object[])getAnnotatedLowerBounds()) ^
 489                 Objects.hash((Object[])getAnnotatedUpperBounds());
 490         }
 491     }
 492 }
< prev index next >