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