Example #1
0
  private static void getFlattenedSuperTypeHierarchyRecursive(
      JClassType type, Set<JClassType> typesSeen) {
    if (typesSeen.contains(type)) {
      return;
    }
    typesSeen.add(type);

    // Check the interfaces
    JClassType[] intfs = type.getImplementedInterfaces();
    for (JClassType intf : intfs) {
      typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf));
    }

    // Superclass
    JClassType superclass = type.getSuperclass();
    if (superclass != null) {
      typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass));
    }
  }
Example #2
0
  /**
   * Find an annotation on a type or on one of its superclasses or superinterfaces.
   *
   * <p>This provides semantics similar to that of {@link java.lang.annotation.Inherited} except
   * that it checks all types to which this type is assignable. {@code @Inherited} only works on
   * superclasses, not superinterfaces.
   *
   * <p>Annotations present on the superclass chain will be returned preferentially over those found
   * in the superinterface hierarchy. Note that the annotation does not need to be tagged with
   * {@code @Inherited} in order to be returned from the superclass chain.
   *
   * @param annotationType the type of the annotation to look for
   * @return the desired annotation or <code>null</code> if the annotation is not present in the
   *     type's type hierarchy
   */
  @Override
  public <T extends Annotation> T findAnnotationInTypeHierarchy(Class<T> annotationType) {

    // Remember what we've seen to avoid loops
    Set<JClassType> seen = new HashSet<JClassType>();

    // Work queue
    List<JClassType> searchTypes = new LinkedList<JClassType>();
    searchTypes.add(this);

    T toReturn = null;

    while (!searchTypes.isEmpty()) {
      JClassType current = searchTypes.remove(0);

      if (!seen.add(current)) {
        continue;
      }

      toReturn = current.getAnnotation(annotationType);
      if (toReturn != null) {
        /*
         * First one wins. It might be desirable at some point to have a
         * variation that can return more than one instance of the annotation if
         * it is present on multiple supertypes.
         */
        break;
      }

      if (current.getSuperclass() != null) {
        // Add the superclass at the front of the list
        searchTypes.add(0, current.getSuperclass());
      }

      // Superinterfaces
      Collections.addAll(searchTypes, current.getImplementedInterfaces());
    }

    return toReturn;
  }