package io.ebean.util; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; /** * Annotation utility methods to find annotations. */ public class AnnotationUtil { /** * Determine if the supplied {@link Annotation} is defined in the core JDK {@code java.lang.annotation} package. */ public static boolean notJavaLang(Annotation annotation) { return !annotation.annotationType().getName().startsWith("java.lang.annotation"); } /** * Simple get on field or method with no meta-annotations or platform filtering. */ public static A get(AnnotatedElement element, Class annotation) { return element.getAnnotation(annotation); } /** * Simple has with no meta-annotations or platform filtering. */ public static boolean has(AnnotatedElement element, Class annotation) { return get(element, annotation) != null; } /** * On class get the annotation - includes inheritance. */ public static A typeGet(Class clazz, Class annotationType) { while (clazz != null && clazz != Object.class) { final A val = clazz.getAnnotation(annotationType); if (val != null) { return val; } clazz = clazz.getSuperclass(); } return null; } /** * On class get all the annotations - includes inheritance. */ public static Set typeGetAll(Class clazz, Class annotationType) { Set result = new LinkedHashSet<>(); typeGetAllCollect(clazz, annotationType, result); return result; } private static void typeGetAllCollect(Class clazz, Class annotationType, Set result) { while (clazz != null && clazz != Object.class) { final A[] annotations = clazz.getAnnotationsByType(annotationType); Collections.addAll(result, annotations); clazz = clazz.getSuperclass(); } } /** * On class simple check for annotation - includes inheritance. */ public static boolean typeHas(Class clazz, Class annotation) { return typeGet(clazz, annotation) != null; } public static boolean metaHas(AnnotatedElement element, Class annotationType) { return !metaFindAll(element, annotationType).isEmpty(); } public static Set metaFindAll(AnnotatedElement element, Class annotationType) { return metaFindAllFor(element, Collections.singleton(annotationType)); } /** * Find all the annotations for the filter searching meta-annotations. */ public static Set metaFindAllFor(AnnotatedElement element, Set> filter) { Set visited = new HashSet<>(); Set result = new LinkedHashSet<>(); for (Annotation ann : element.getAnnotations()) { metaAdd(ann, filter, visited, result); } return result; } private static void metaAdd(Annotation ann, Set> filter, Set visited, Set result) { if (notJavaLang(ann) && visited.add(ann)) { if (filter.contains(ann.annotationType())) { result.add(ann); } else { for (Annotation metaAnn : ann.annotationType().getAnnotations()) { metaAdd(metaAnn, filter, visited, result); } } } } }