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 public MetaAnnotationTypeFilter(Class<? extends Annotation> annotation, ClassLoader classLoader)
44 {
45 this.annotation = annotation;
46 this.classLoader = classLoader;
47 }
48
49
50
51
52
53
54 public MetaAnnotationTypeFilter(Class<? extends Annotation> annotation)
55 {
56 this.annotation = annotation;
57 classLoader = Thread.currentThread().getContextClassLoader();
58 }
59
60 public boolean accept(AnnotationInfo info)
61 {
62 try
63 {
64 URL classUrl = getClassURL(info.getClassName());
65 if (classUrl == null)
66 {
67 logger.debug("Failed to load annotation class: " + info);
68 return false;
69 }
70
71 InputStream classStream = classUrl.openStream();
72 ClassReader r = new ClosableClassReader(classStream);
73
74 MetaAnnotationScanner scanner = new MetaAnnotationScanner(new AnnotationTypeFilter(annotation));
75 r.accept(scanner, 0);
76
77 return scanner.getClassAnnotations().size() == 1;
78 }
79 catch (IOException e)
80 {
81 logger.debug(e);
82 return false;
83 }
84 }
85
86 private class MetaAnnotationScanner extends AnnotationsScanner
87 {
88 public MetaAnnotationScanner(AnnotationFilter filter)
89 {
90 super(filter);
91 }
92
93 @Override
94 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible)
95 {
96 currentAnnotation = new AnnotationInfo();
97 currentAnnotation.setClassName(getAnnotationClassName(desc));
98 if (log.isDebugEnabled())
99 {
100 log.debug("Annotation: " + getAnnotationClassName(desc));
101 }
102
103
104 if (currentlyProcessing.nextSetBit(0) < 0)
105 {
106
107 currentlyProcessing.set(PROCESSING_CLASS);
108 }
109
110 return this;
111 }
112
113 }
114
115 public URL getClassURL(String className)
116 {
117 String resource = className.replace(".", "/") + ".class";
118 return classLoader.getResource(resource);
119 }
120 }