Allow for recursive annotations (#97)

Co-authored-by: Mariell <proximyst@proximyst.com>
This commit is contained in:
Alexander Söderberg 2020-10-24 19:28:56 +02:00
parent e26d01388d
commit a68bc0bea7
3 changed files with 99 additions and 6 deletions

View file

@ -51,11 +51,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
@ -106,16 +108,40 @@ public final class AnnotationParser<C> {
));
}
@SuppressWarnings("unchecked")
static <A extends Annotation> @Nullable A getAnnotationRecursively(
final @NonNull Annotation[] annotations,
final @NonNull Class<A> clazz,
final @NonNull Set<Class<? extends Annotation>> checkedAnnotations
) {
A innerCandidate = null;
for (final Annotation annotation : annotations) {
if (!checkedAnnotations.add(annotation.annotationType())) {
continue;
}
if (annotation.annotationType().equals(clazz)) {
return (A) annotation;
}
if (annotation.annotationType().getPackage().getName().startsWith("java.lang")) {
continue;
}
final A inner = getAnnotationRecursively(annotation.annotationType().getAnnotations(), clazz, checkedAnnotations);
if (inner != null) {
innerCandidate = inner;
}
}
return innerCandidate;
}
static <A extends Annotation> @Nullable A getMethodOrClassAnnotation(
final @NonNull Method method,
final @NonNull Class<A> clazz
) {
if (method.isAnnotationPresent(clazz)) {
return method.getAnnotation(clazz);
} else if (method.getDeclaringClass().isAnnotationPresent(clazz)) {
return method.getDeclaringClass().getAnnotation(clazz);
A annotation = getAnnotationRecursively(method.getAnnotations(), clazz, new HashSet<>());
if (annotation == null) {
annotation = getAnnotationRecursively(method.getDeclaringClass().getAnnotations(), clazz, new HashSet<>());
}
return null;
return annotation;
}
static <A extends Annotation> boolean methodOrClassHasAnnotation(