1
2
3
4
5
6
7
8
9
10 package org.mule.util.scan.annotations;
11
12 import org.mule.util.scan.ClassScanner;
13
14 import java.util.ArrayList;
15 import java.util.BitSet;
16 import java.util.List;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.objectweb.asm.AnnotationVisitor;
21 import org.objectweb.asm.FieldVisitor;
22 import org.objectweb.asm.MethodVisitor;
23 import org.objectweb.asm.commons.EmptyVisitor;
24
25
26
27
28
29
30
31
32 public class AnnotationsScanner extends EmptyVisitor implements ClassScanner
33 {
34 protected final Log log = LogFactory.getLog(getClass());
35
36 private List<AnnotationInfo> classAnnotations = new ArrayList<AnnotationInfo>();
37 private List<AnnotationInfo> fieldAnnotations = new ArrayList<AnnotationInfo>();
38 private List<AnnotationInfo> methodAnnotations = new ArrayList<AnnotationInfo>();
39 private List<AnnotationInfo> paramAnnotations = new ArrayList<AnnotationInfo>();
40
41 protected AnnotationInfo currentAnnotation;
42
43 protected static final int PROCESSING_FIELD = 1;
44 protected static final int PROCESSING_METHOD = 2;
45 protected static final int PROCESSING_CLASS = 3;
46 protected static final int PROCESSING_PARAM = 4;
47
48 protected BitSet currentlyProcessing = new BitSet(4);
49
50 private AnnotationFilter filter;
51
52 private BitSet lastProcessing = null;
53
54 private String className;
55
56 private boolean match;
57
58 public AnnotationsScanner()
59 {
60 super();
61 }
62
63 public AnnotationsScanner(AnnotationFilter filter)
64 {
65 this.filter = filter;
66 }
67
68 @Override
69 public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible)
70 {
71 currentAnnotation = new AnnotationInfo();
72 currentAnnotation.setClassName(getAnnotationClassName(desc));
73 currentlyProcessing.set(PROCESSING_PARAM);
74 if (log.isDebugEnabled())
75 {
76 log.debug("Parameter Annotation: " + getAnnotationClassName(desc));
77 }
78 return this;
79 }
80
81 @Override
82 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible)
83 {
84
85 if (currentlyProcessing.nextSetBit(0) < 0)
86 {
87 if(lastProcessing!=null)
88 {
89 currentlyProcessing = lastProcessing;
90 }
91 else
92 {
93 return this;
94 }
95 }
96
97 currentAnnotation = new AnnotationInfo();
98 currentAnnotation.setClassName(getAnnotationClassName(desc));
99 if (log.isDebugEnabled())
100 {
101 log.debug("Annotation: " + getAnnotationClassName(desc));
102 }
103
104 return this;
105 }
106
107
108
109
110
111 @Override
112 public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)
113 {
114 currentlyProcessing.set(PROCESSING_CLASS);
115 className = name;
116 }
117
118
119
120
121 @Override
122 public void visit(String name, Object value)
123 {
124 if (currentAnnotation != null)
125 {
126 currentAnnotation.getParams().add(new AnnotationInfo.NameValue(name, value));
127 }
128 if (log.isDebugEnabled())
129 {
130
131 log.debug(" : " + name + "=" + value);
132 }
133 }
134
135 @Override
136 public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value)
137 {
138 currentlyProcessing.set(PROCESSING_FIELD);
139 return this;
140 }
141
142 @Override
143 public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)
144 {
145 currentlyProcessing.set(PROCESSING_METHOD);
146 return this;
147 }
148
149
150 @Override
151 public void visitEnd()
152 {
153 if (currentAnnotation != null)
154 {
155
156 if(filter!=null && !filter.accept(currentAnnotation))
157 {
158 currentlyProcessing.clear();
159 currentAnnotation = null;
160 return;
161 }
162 if (currentlyProcessing.get(PROCESSING_CLASS))
163 {
164 classAnnotations.add(currentAnnotation);
165 match = true;
166 }
167 if (currentlyProcessing.get(PROCESSING_FIELD))
168 {
169 fieldAnnotations.add(currentAnnotation);
170 match = true;
171 }
172 else if (currentlyProcessing.get(PROCESSING_PARAM))
173 {
174 paramAnnotations.add(currentAnnotation);
175 match = true;
176 }
177 else if (currentlyProcessing.get(PROCESSING_METHOD))
178 {
179 methodAnnotations.add(currentAnnotation);
180 match = true;
181 }
182 currentAnnotation = null;
183 }
184 lastProcessing = (BitSet)currentlyProcessing.clone();
185 currentlyProcessing.clear();
186
187 }
188
189 public String getAnnotationClassName(String rawName)
190 {
191 return rawName.substring(1, rawName.length() - 1).replace('/', '.');
192 }
193
194 public List<AnnotationInfo> getClassAnnotations()
195 {
196 return classAnnotations;
197 }
198
199 public List<AnnotationInfo> getFieldAnnotations()
200 {
201 return fieldAnnotations;
202 }
203
204 public List<AnnotationInfo> getMethodAnnotations()
205 {
206 return methodAnnotations;
207 }
208
209 public List<AnnotationInfo> getParamAnnotations()
210 {
211 return paramAnnotations;
212 }
213
214 public List<AnnotationInfo> getAllAnnotations()
215 {
216 List<AnnotationInfo> list = new ArrayList<AnnotationInfo>();
217 list.addAll(classAnnotations);
218 list.addAll(fieldAnnotations);
219 list.addAll(methodAnnotations);
220 list.addAll(paramAnnotations);
221 return list;
222 }
223
224 public boolean isMatch()
225 {
226 return match;
227 }
228
229 public String getClassName()
230 {
231 return className;
232 }
233 }