rulebook-core/src/main/java/com/deliveredtechnologies/rulebook/util/AnnotationUtils.java
@SuppressWarnings("unchecked")
  public static <A extends Annotation> A getAnnotation(Class<A> annotation, Class<?> clazz) {
    return Optional.ofNullable(clazz.getAnnotation(annotation)).orElse((A)
      Arrays.stream(clazz.getDeclaredAnnotations())
        .flatMap(anno -> Arrays.stream(anno.getClass().getInterfaces())
          .flatMap(iface -> Arrays.stream(iface.getDeclaredAnnotations())))
        .filter(annotation::isInstance)
        .findFirst().orElse(null)
    );
  }
@SuppressWarnings("unchecked")
  public static <A extends Annotation> A getAnnotation(Class<A> annotation, Class<?> clazz) {
    return Optional.ofNullable(clazz.getAnnotation(annotation)).orElse((A)
      Arrays.stream(clazz.getDeclaredAnnotations())
        .flatMap(anno -> Arrays.stream(anno.getClass().getInterfaces())
          .flatMap(iface -> Arrays.stream(iface.getDeclaredAnnotations())))
        .filter(annotation::isInstance)
        .findFirst().orElse(null)
    );
  }
@ SuppressWarnings ( "unchecked" ) public static < A extends Annotation > A getAnnotation ( Class < A > annotation , Class < ? > clazz ) { return Optional . ofNullable ( clazz . getAnnotation ( annotation ) ) . orElse ( ( A ) Arrays . stream ( clazz . getDeclaredAnnotations ( ) ) . flatMap ( anno -> Arrays . stream ( anno . getClass ( ) . getInterfaces ( ) ) . flatMap ( iface -> Arrays . stream ( iface . getDeclaredAnnotations ( ) ) ) ) . filter ( annotation :: isInstance ) . findFirst ( ) . orElse ( null ) ) ; }
Method getAnnotation returns the annotation on a class or its parent annotation.
@param clazz       the annotated class
@param annotation  the annotation to find
@param <A>         the type of the annotation
@return            the actual annotation used or null if it doesn't exist
Method getAnnotation returns the annotation on a class or its parent annotation .