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