1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.util.Stack;
20
21 /***
22 * Traverses a JavaClass with another Visitor object 'piggy-backed'
23 * that is applied to all components of a JavaClass object. I.e. this
24 * class supplies the traversal strategy, other classes can make use
25 * of it.
26 *
27 * @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $
28 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
29 */
30 public class DescendingVisitor implements Visitor {
31
32 private JavaClass clazz;
33 private Visitor visitor;
34 private Stack stack = new Stack();
35
36
37 /*** @return container of current entitity, i.e., predecessor during traversal
38 */
39 public Object predecessor() {
40 return predecessor(0);
41 }
42
43
44 /***
45 * @param level nesting level, i.e., 0 returns the direct predecessor
46 * @return container of current entitity, i.e., predecessor during traversal
47 */
48 public Object predecessor( int level ) {
49 int size = stack.size();
50 if ((size < 2) || (level < 0)) {
51 return null;
52 } else {
53 return stack.elementAt(size - (level + 2));
54 }
55 }
56
57
58 /*** @return current object
59 */
60 public Object current() {
61 return stack.peek();
62 }
63
64
65 /***
66 * @param clazz Class to traverse
67 * @param visitor visitor object to apply to all components
68 */
69 public DescendingVisitor(JavaClass clazz, Visitor visitor) {
70 this.clazz = clazz;
71 this.visitor = visitor;
72 }
73
74
75 /***
76 * Start traversal.
77 */
78 public void visit() {
79 clazz.accept(this);
80 }
81
82
83 public void visitJavaClass( JavaClass _clazz ) {
84 stack.push(_clazz);
85 _clazz.accept(visitor);
86 Field[] fields = _clazz.getFields();
87 for (int i = 0; i < fields.length; i++) {
88 fields[i].accept(this);
89 }
90 Method[] methods = _clazz.getMethods();
91 for (int i = 0; i < methods.length; i++) {
92 methods[i].accept(this);
93 }
94 Attribute[] attributes = _clazz.getAttributes();
95 for (int i = 0; i < attributes.length; i++) {
96 attributes[i].accept(this);
97 }
98 _clazz.getConstantPool().accept(this);
99 stack.pop();
100 }
101
102
103 public void visitField( Field field ) {
104 stack.push(field);
105 field.accept(visitor);
106 Attribute[] attributes = field.getAttributes();
107 for (int i = 0; i < attributes.length; i++) {
108 attributes[i].accept(this);
109 }
110 stack.pop();
111 }
112
113
114 public void visitConstantValue( ConstantValue cv ) {
115 stack.push(cv);
116 cv.accept(visitor);
117 stack.pop();
118 }
119
120
121 public void visitMethod( Method method ) {
122 stack.push(method);
123 method.accept(visitor);
124 Attribute[] attributes = method.getAttributes();
125 for (int i = 0; i < attributes.length; i++) {
126 attributes[i].accept(this);
127 }
128 stack.pop();
129 }
130
131
132 public void visitExceptionTable( ExceptionTable table ) {
133 stack.push(table);
134 table.accept(visitor);
135 stack.pop();
136 }
137
138
139 public void visitCode( Code code ) {
140 stack.push(code);
141 code.accept(visitor);
142 CodeException[] table = code.getExceptionTable();
143 for (int i = 0; i < table.length; i++) {
144 table[i].accept(this);
145 }
146 Attribute[] attributes = code.getAttributes();
147 for (int i = 0; i < attributes.length; i++) {
148 attributes[i].accept(this);
149 }
150 stack.pop();
151 }
152
153
154 public void visitCodeException( CodeException ce ) {
155 stack.push(ce);
156 ce.accept(visitor);
157 stack.pop();
158 }
159
160
161 public void visitLineNumberTable( LineNumberTable table ) {
162 stack.push(table);
163 table.accept(visitor);
164 LineNumber[] numbers = table.getLineNumberTable();
165 for (int i = 0; i < numbers.length; i++) {
166 numbers[i].accept(this);
167 }
168 stack.pop();
169 }
170
171
172 public void visitLineNumber( LineNumber number ) {
173 stack.push(number);
174 number.accept(visitor);
175 stack.pop();
176 }
177
178
179 public void visitLocalVariableTable( LocalVariableTable table ) {
180 stack.push(table);
181 table.accept(visitor);
182 LocalVariable[] vars = table.getLocalVariableTable();
183 for (int i = 0; i < vars.length; i++) {
184 vars[i].accept(this);
185 }
186 stack.pop();
187 }
188
189
190 public void visitStackMap( StackMap table ) {
191 stack.push(table);
192 table.accept(visitor);
193 StackMapEntry[] vars = table.getStackMap();
194 for (int i = 0; i < vars.length; i++) {
195 vars[i].accept(this);
196 }
197 stack.pop();
198 }
199
200
201 public void visitStackMapEntry( StackMapEntry var ) {
202 stack.push(var);
203 var.accept(visitor);
204 stack.pop();
205 }
206
207
208 public void visitLocalVariable( LocalVariable var ) {
209 stack.push(var);
210 var.accept(visitor);
211 stack.pop();
212 }
213
214
215 public void visitConstantPool( ConstantPool cp ) {
216 stack.push(cp);
217 cp.accept(visitor);
218 Constant[] constants = cp.getConstantPool();
219 for (int i = 1; i < constants.length; i++) {
220 if (constants[i] != null) {
221 constants[i].accept(this);
222 }
223 }
224 stack.pop();
225 }
226
227
228 public void visitConstantClass( ConstantClass constant ) {
229 stack.push(constant);
230 constant.accept(visitor);
231 stack.pop();
232 }
233
234
235 public void visitConstantDouble( ConstantDouble constant ) {
236 stack.push(constant);
237 constant.accept(visitor);
238 stack.pop();
239 }
240
241
242 public void visitConstantFieldref( ConstantFieldref constant ) {
243 stack.push(constant);
244 constant.accept(visitor);
245 stack.pop();
246 }
247
248
249 public void visitConstantFloat( ConstantFloat constant ) {
250 stack.push(constant);
251 constant.accept(visitor);
252 stack.pop();
253 }
254
255
256 public void visitConstantInteger( ConstantInteger constant ) {
257 stack.push(constant);
258 constant.accept(visitor);
259 stack.pop();
260 }
261
262
263 public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref constant ) {
264 stack.push(constant);
265 constant.accept(visitor);
266 stack.pop();
267 }
268
269
270 public void visitConstantLong( ConstantLong constant ) {
271 stack.push(constant);
272 constant.accept(visitor);
273 stack.pop();
274 }
275
276
277 public void visitConstantMethodref( ConstantMethodref constant ) {
278 stack.push(constant);
279 constant.accept(visitor);
280 stack.pop();
281 }
282
283
284 public void visitConstantNameAndType( ConstantNameAndType constant ) {
285 stack.push(constant);
286 constant.accept(visitor);
287 stack.pop();
288 }
289
290
291 public void visitConstantString( ConstantString constant ) {
292 stack.push(constant);
293 constant.accept(visitor);
294 stack.pop();
295 }
296
297
298 public void visitConstantUtf8( ConstantUtf8 constant ) {
299 stack.push(constant);
300 constant.accept(visitor);
301 stack.pop();
302 }
303
304
305 public void visitInnerClasses( InnerClasses ic ) {
306 stack.push(ic);
307 ic.accept(visitor);
308 InnerClass[] ics = ic.getInnerClasses();
309 for (int i = 0; i < ics.length; i++) {
310 ics[i].accept(this);
311 }
312 stack.pop();
313 }
314
315
316 public void visitInnerClass( InnerClass inner ) {
317 stack.push(inner);
318 inner.accept(visitor);
319 stack.pop();
320 }
321
322
323 public void visitDeprecated( Deprecated attribute ) {
324 stack.push(attribute);
325 attribute.accept(visitor);
326 stack.pop();
327 }
328
329
330 public void visitSignature( Signature attribute ) {
331 stack.push(attribute);
332 attribute.accept(visitor);
333 stack.pop();
334 }
335
336
337 public void visitSourceFile( SourceFile attribute ) {
338 stack.push(attribute);
339 attribute.accept(visitor);
340 stack.pop();
341 }
342
343
344 public void visitSynthetic( Synthetic attribute ) {
345 stack.push(attribute);
346 attribute.accept(visitor);
347 stack.pop();
348 }
349
350
351 public void visitUnknown( Unknown attribute ) {
352 stack.push(attribute);
353 attribute.accept(visitor);
354 stack.pop();
355 }
356 }