001 /*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005 package org.bridj.util;
006
007 import java.lang.annotation.Annotation;
008 import java.lang.reflect.AnnotatedElement;
009 import java.lang.reflect.Member;
010 import java.lang.reflect.Proxy;
011 import org.bridj.ann.Forwardable;
012
013 /**
014 * Util methods for annotations (inheritable annotations, forwarded annotations, annotations from AnnotatedElements and/or direct annotation arrays...)
015 * @author ochafik
016 */
017 public class AnnotationUtils {
018
019 public static <A extends Annotation> A getInheritableAnnotation(Class<A> ac, AnnotatedElement m, Annotation... directAnnotations) {
020 return getAnnotation(ac, true, m, directAnnotations);
021 }
022 public static <A extends Annotation> A getAnnotation(Class<A> ac, AnnotatedElement m, Annotation... directAnnotations) {
023 return getAnnotation(ac, false, m, directAnnotations);
024 }
025 private static boolean isForwardable(Class<? extends Annotation> ac) {
026 return ac.isAnnotationPresent(Forwardable.class);
027 }
028 public static boolean isAnnotationPresent(Class<? extends Annotation> ac, Annotation... annotations) {
029 return isAnnotationPresent(ac, isForwardable(ac), annotations);
030 }
031 private static boolean isAnnotationPresent(Class<? extends Annotation> ac, boolean isForwardable, Annotation... annotations) {
032 for (Annotation ann : annotations) {
033 if (ac.isInstance(ann))
034 return true;
035
036 if (isForwardable) {
037 if (ann.annotationType().isAnnotationPresent(ac))
038 return true;
039 }
040 }
041 return false;
042 }
043 public static boolean isAnnotationPresent(Class<? extends Annotation> ac, AnnotatedElement m, Annotation... directAnnotations) {
044 boolean isForwardable = isForwardable(ac);
045 if (m != null) {
046 if (isForwardable) {
047 if (isAnnotationPresent(ac, true, m.getAnnotations()))
048 return true;
049 } else {
050 if (m.isAnnotationPresent(ac))
051 return true;
052 }
053 }
054 if (directAnnotations != null)
055 return isAnnotationPresent(ac, isForwardable, directAnnotations);
056
057 return false;
058 }
059
060 private static <A extends Annotation> A getAnnotation(Class<A> ac, boolean inherit, AnnotatedElement m, Annotation... directAnnotations) {
061 if (directAnnotations != null) {
062 for (Annotation ann : directAnnotations) {
063 if (ac.isInstance(ann)) {
064 return ac.cast(ann);
065 }
066 }
067 }
068
069 if (m == null) {
070 return null;
071 }
072 A a = m.getAnnotation(ac);
073 if (a != null) {
074 return a;
075 }
076
077 if (inherit) {
078 if (m instanceof Member) {
079 return getAnnotation(ac, inherit, ((Member) m).getDeclaringClass());
080 }
081
082 if (m instanceof Class<?>) {
083 Class<?> c = (Class<?>) m, dc = c.getDeclaringClass();
084 Class p = c.getSuperclass();
085 while (p != null) {
086 a = getAnnotation(ac, true, p);
087 if (a != null)
088 return a;
089 p = p.getSuperclass();
090 }
091
092 if (dc != null) {
093 return getAnnotation(ac, inherit, dc);
094 }
095 }
096 }
097 return null;
098 }
099 }