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