001package io.ebean.util; 002 003import java.lang.annotation.Annotation; 004import java.lang.reflect.AnnotatedElement; 005import java.util.Collections; 006import java.util.HashSet; 007import java.util.LinkedHashSet; 008import java.util.Set; 009 010/** 011 * Annotation utility methods to find annotations. 012 */ 013public class AnnotationUtil { 014 015 /** 016 * Determine if the supplied {@link Annotation} is defined in the core JDK {@code java.lang.annotation} package. 017 */ 018 public static boolean notJavaLang(Annotation annotation) { 019 return !annotation.annotationType().getName().startsWith("java.lang.annotation"); 020 } 021 022 /** 023 * Simple get on field or method with no meta-annotations or platform filtering. 024 */ 025 public static <A extends Annotation> A get(AnnotatedElement element, Class<A> annotation) { 026 return element.getAnnotation(annotation); 027 } 028 029 /** 030 * Simple has with no meta-annotations or platform filtering. 031 */ 032 public static <A extends Annotation> boolean has(AnnotatedElement element, Class<A> annotation) { 033 return get(element, annotation) != null; 034 } 035 036 /** 037 * On class get the annotation - includes inheritance. 038 */ 039 public static <A extends Annotation> A typeGet(Class<?> clazz, Class<A> annotationType) { 040 while (clazz != null && clazz != Object.class) { 041 final A val = clazz.getAnnotation(annotationType); 042 if (val != null) { 043 return val; 044 } 045 clazz = clazz.getSuperclass(); 046 } 047 return null; 048 } 049 050 /** 051 * On class get all the annotations - includes inheritance. 052 */ 053 public static <A extends Annotation> Set<A> typeGetAll(Class<?> clazz, Class<A> annotationType) { 054 Set<A> result = new LinkedHashSet<>(); 055 typeGetAllCollect(clazz, annotationType, result); 056 return result; 057 } 058 059 private static <A extends Annotation> void typeGetAllCollect(Class<?> clazz, Class<A> annotationType, Set<A> result) { 060 while (clazz != null && clazz != Object.class) { 061 final A[] annotations = clazz.getAnnotationsByType(annotationType); 062 Collections.addAll(result, annotations); 063 clazz = clazz.getSuperclass(); 064 } 065 } 066 067 /** 068 * On class simple check for annotation - includes inheritance. 069 */ 070 public static <A extends Annotation> boolean typeHas(Class<?> clazz, Class<A> annotation) { 071 return typeGet(clazz, annotation) != null; 072 } 073 074 /** 075 * Find all the annotations for the filter searching meta-annotations. 076 */ 077 public static Set<Annotation> metaFindAllFor(AnnotatedElement element, Set<Class<?>> filter) { 078 Set<Annotation> visited = new HashSet<>(); 079 Set<Annotation> result = new LinkedHashSet<>(); 080 for (Annotation ann : element.getAnnotations()) { 081 metaAdd(ann, filter, visited, result); 082 } 083 return result; 084 } 085 086 private static void metaAdd(Annotation ann, Set<Class<?>> filter, Set<Annotation> visited, Set<Annotation> result) { 087 if (notJavaLang(ann) && visited.add(ann)) { 088 if (filter.contains(ann.annotationType())) { 089 result.add(ann); 090 } else { 091 for (Annotation metaAnn : ann.annotationType().getAnnotations()) { 092 metaAdd(metaAnn, filter, visited, result); 093 } 094 } 095 } 096 } 097}