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 }