View Javadoc

1   /*
2    * Copyright  2000-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License"); 
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License. 
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)); // size - 1 == current
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 }