1
2
3
4
5
6
7
8
9
10 package org.mule.util.scan.annotations;
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.lang.annotation.Annotation;
15 import java.net.URL;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.objectweb.asm.AnnotationVisitor;
20 import org.objectweb.asm.ClassReader;
21
22
23
24
25
26 public class MetaAnnotationTypeFilter implements AnnotationFilter
27 {
28
29
30
31 protected transient final Log logger = LogFactory.getLog(MetaAnnotationTypeFilter.class);
32
33 private Class<? extends Annotation> annotation;
34
35 private ClassLoader classLoader;
36
37
38
39
40
41
42
43
44
45 public MetaAnnotationTypeFilter(Class<? extends Annotation> annotation, ClassLoader classLoader)
46 {
47 this.annotation = annotation;
48 this.classLoader = classLoader;
49 }
50
51
52
53
54
55
56 public MetaAnnotationTypeFilter(Class<? extends Annotation> annotation)
57 {
58 this.annotation = annotation;
59 classLoader = Thread.currentThread().getContextClassLoader();
60 }
61
62 public boolean accept(AnnotationInfo info)
63 {
64 try
65 {
66 URL classUrl = getClassURL(info.getClassName());
67 if (classUrl == null)
68 {
69 logger.debug("Failed to load annotation class: " + info);
70 return false;
71 }
72
73 InputStream classStream = classUrl.openStream();
74 ClassReader r = new ClosableClassReader(classStream);
75
76 MetaAnnotationScanner scanner = new MetaAnnotationScanner(new AnnotationTypeFilter(annotation));
77 r.accept(scanner, 0);
78
79 return scanner.getClassAnnotations().size() == 1;
80 }
81 catch (IOException e)
82 {
83 logger.debug(e);
84 return false;
85 }
86 }
87
88 private class MetaAnnotationScanner extends AnnotationsScanner
89 {
90 public MetaAnnotationScanner(AnnotationFilter filter)
91 {
92 super(filter);
93 }
94
95 @Override
96 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible)
97 {
98 currentAnnotation = new AnnotationInfo();
99 currentAnnotation.setClassName(getAnnotationClassName(desc));
100 if (log.isDebugEnabled())
101 {
102 log.debug("Annotation: " + getAnnotationClassName(desc));
103 }
104
105
106 if (currentlyProcessing.nextSetBit(0) < 0)
107 {
108
109 currentlyProcessing.set(PROCESSING_CLASS);
110 }
111
112 return this;
113 }
114
115 }
116
117 public URL getClassURL(String className)
118 {
119 String resource = className.replace(".", "/") + ".class";
120 return classLoader.getResource(resource);
121 }
122 }