1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 package com.sun.org.apache.bcel.internal.classfile;
   6 
   7 /* ====================================================================
   8  * The Apache Software License, Version 1.1
   9  *
  10  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  11  * reserved.
  12  *
  13  * Redistribution and use in source and binary forms, with or without
  14  * modification, are permitted provided that the following conditions
  15  * are met:
  16  *
  17  * 1. Redistributions of source code must retain the above copyright
  18  *    notice, this list of conditions and the following disclaimer.
  19  *
  20  * 2. Redistributions in binary form must reproduce the above copyright
  21  *    notice, this list of conditions and the following disclaimer in
  22  *    the documentation and/or other materials provided with the
  23  *    distribution.
  24  *
  25  * 3. The end-user documentation included with the redistribution,
  26  *    if any, must include the following acknowledgment:
  27  *       "This product includes software developed by the
  28  *        Apache Software Foundation (http://www.apache.org/)."
  29  *    Alternately, this acknowledgment may appear in the software itself,
  30  *    if and wherever such third-party acknowledgments normally appear.
  31  *
  32  * 4. The names "Apache" and "Apache Software Foundation" and
  33  *    "Apache BCEL" must not be used to endorse or promote products
  34  *    derived from this software without prior written permission. For
  35  *    written permission, please contact apache@apache.org.
  36  *
  37  * 5. Products derived from this software may not be called "Apache",
  38  *    "Apache BCEL", nor may "Apache" appear in their name, without
  39  *    prior written permission of the Apache Software Foundation.
  40  *
  41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52  * SUCH DAMAGE.
  53  * ====================================================================
  54  *
  55  * This software consists of voluntary contributions made by many
  56  * individuals on behalf of the Apache Software Foundation.  For more
  57  * information on the Apache Software Foundation, please see
  58  * <http://www.apache.org/>.
  59  */
  60 import java.util.Stack;
  61 
  62 /**
  63  * Traverses a JavaClass with another Visitor object 'piggy-backed'
  64  * that is applied to all components of a JavaClass object. I.e. this
  65  * class supplies the traversal strategy, other classes can make use
  66  * of it.
  67  *
  68  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  69  */
  70 public class DescendingVisitor implements Visitor {
  71   private JavaClass clazz;
  72   private Visitor   visitor;
  73   private Stack     stack = new Stack();
  74 
  75   /** @return container of current entitity, i.e., predecessor during traversal
  76    */
  77   public Object predecessor() {
  78     return predecessor(0);
  79   }
  80 
  81   /**
  82    * @param level nesting level, i.e., 0 returns the direct predecessor
  83    * @return container of current entitity, i.e., predecessor during traversal
  84    */
  85   public Object predecessor(int level) {
  86     int size = stack.size();
  87 
  88     if((size < 2) || (level < 0))
  89       return null;
  90     else
  91       return stack.elementAt(size - (level + 2)); // size - 1 == current
  92   }
  93 
  94   /** @return current object
  95    */
  96   public Object current() {
  97     return stack.peek();
  98   }
  99 
 100   /**
 101    * @param clazz Class to traverse
 102    * @param visitor visitor object to apply to all components
 103    */
 104   public DescendingVisitor(JavaClass clazz, Visitor visitor) {
 105     this.clazz   = clazz;
 106     this.visitor = visitor;
 107   }
 108 
 109   /**
 110    * Start traversal.
 111    */
 112   public void visit() { clazz.accept(this); }
 113 
 114   public void visitJavaClass(JavaClass clazz) {
 115     stack.push(clazz);
 116     clazz.accept(visitor);
 117 
 118     Field[] fields = clazz.getFields();
 119     for(int i=0; i < fields.length; i++)
 120       fields[i].accept(this);
 121 
 122     Method[] methods = clazz.getMethods();
 123     for(int i=0; i < methods.length; i++)
 124       methods[i].accept(this);
 125 
 126     Attribute[] attributes = clazz.getAttributes();
 127     for(int i=0; i < attributes.length; i++)
 128       attributes[i].accept(this);
 129 
 130     clazz.getConstantPool().accept(this);
 131     stack.pop();
 132   }
 133 
 134   public void visitField(Field field) {
 135     stack.push(field);
 136     field.accept(visitor);
 137 
 138     Attribute[] attributes = field.getAttributes();
 139     for(int i=0; i < attributes.length; i++)
 140       attributes[i].accept(this);
 141     stack.pop();
 142   }
 143 
 144   public void visitConstantValue(ConstantValue cv) {
 145     stack.push(cv);
 146     cv.accept(visitor);
 147     stack.pop();
 148   }
 149 
 150   public void visitMethod(Method method) {
 151     stack.push(method);
 152     method.accept(visitor);
 153 
 154     Attribute[] attributes = method.getAttributes();
 155     for(int i=0; i < attributes.length; i++)
 156       attributes[i].accept(this);
 157 
 158     stack.pop();
 159   }
 160 
 161   public void visitExceptionTable(ExceptionTable table) {
 162     stack.push(table);
 163     table.accept(visitor);
 164     stack.pop();
 165   }
 166 
 167   public void visitCode(Code code) {
 168     stack.push(code);
 169     code.accept(visitor);
 170 
 171     CodeException[] table = code.getExceptionTable();
 172     for(int i=0; i < table.length; i++)
 173       table[i].accept(this);
 174 
 175     Attribute[] attributes = code.getAttributes();
 176     for(int i=0; i < attributes.length; i++)
 177       attributes[i].accept(this);
 178     stack.pop();
 179   }
 180 
 181   public void visitCodeException(CodeException ce) {
 182     stack.push(ce);
 183     ce.accept(visitor);
 184     stack.pop();
 185   }
 186 
 187   public void visitLineNumberTable(LineNumberTable table) {
 188     stack.push(table);
 189     table.accept(visitor);
 190 
 191     LineNumber[] numbers = table.getLineNumberTable();
 192     for(int i=0; i < numbers.length; i++)
 193       numbers[i].accept(this);
 194     stack.pop();
 195   }
 196 
 197   public void visitLineNumber(LineNumber number) {
 198     stack.push(number);
 199     number.accept(visitor);
 200     stack.pop();
 201   }
 202 
 203   public void visitLocalVariableTable(LocalVariableTable table) {
 204     stack.push(table);
 205     table.accept(visitor);
 206 
 207     LocalVariable[] vars = table.getLocalVariableTable();
 208     for(int i=0; i < vars.length; i++)
 209       vars[i].accept(this);
 210     stack.pop();
 211   }
 212 
 213   public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {
 214     stack.push(obj);
 215     obj.accept(visitor);
 216 
 217     LocalVariable[] vars = obj.getLocalVariableTypeTable();
 218     for(int i=0; i < vars.length; i++)
 219       vars[i].accept(this);
 220     stack.pop();
 221   }
 222 
 223   public void visitStackMap(StackMap table) {
 224     stack.push(table);
 225     table.accept(visitor);
 226 
 227     StackMapEntry[] vars = table.getStackMap();
 228 
 229     for(int i=0; i < vars.length; i++)
 230       vars[i].accept(this);
 231     stack.pop();
 232   }
 233 
 234   public void visitStackMapEntry(StackMapEntry var) {
 235     stack.push(var);
 236     var.accept(visitor);
 237     stack.pop();
 238   }
 239 
 240   public void visitLocalVariable(LocalVariable var) {
 241     stack.push(var);
 242     var.accept(visitor);
 243     stack.pop();
 244   }
 245 
 246   public void visitConstantPool(ConstantPool cp) {
 247     stack.push(cp);
 248     cp.accept(visitor);
 249 
 250     Constant[] constants = cp.getConstantPool();
 251     for(int i=1; i < constants.length; i++) {
 252       if(constants[i] != null)
 253         constants[i].accept(this);
 254     }
 255 
 256     stack.pop();
 257   }
 258 
 259   public void visitConstantClass(ConstantClass constant) {
 260     stack.push(constant);
 261     constant.accept(visitor);
 262     stack.pop();
 263   }
 264 
 265   public void visitConstantDouble(ConstantDouble constant) {
 266     stack.push(constant);
 267     constant.accept(visitor);
 268     stack.pop();
 269   }
 270 
 271   public void visitConstantFieldref(ConstantFieldref constant) {
 272     stack.push(constant);
 273     constant.accept(visitor);
 274     stack.pop();
 275   }
 276 
 277   public void visitConstantFloat(ConstantFloat constant) {
 278     stack.push(constant);
 279     constant.accept(visitor);
 280     stack.pop();
 281  }
 282 
 283   public void visitConstantInteger(ConstantInteger constant) {
 284     stack.push(constant);
 285     constant.accept(visitor);
 286     stack.pop();
 287   }
 288 
 289   public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) {
 290     stack.push(constant);
 291     constant.accept(visitor);
 292     stack.pop();
 293   }
 294 
 295   public void visitConstantLong(ConstantLong constant) {
 296     stack.push(constant);
 297     constant.accept(visitor);
 298     stack.pop();
 299   }
 300 
 301   public void visitConstantMethodref(ConstantMethodref constant) {
 302     stack.push(constant);
 303     constant.accept(visitor);
 304     stack.pop();
 305   }
 306 
 307   public void visitConstantNameAndType(ConstantNameAndType constant) {
 308     stack.push(constant);
 309     constant.accept(visitor);
 310     stack.pop();
 311   }
 312 
 313   public void visitConstantString(ConstantString constant) {
 314     stack.push(constant);
 315     constant.accept(visitor);
 316     stack.pop();
 317   }
 318 
 319   public void visitConstantUtf8(ConstantUtf8 constant) {
 320     stack.push(constant);
 321     constant.accept(visitor);
 322     stack.pop();
 323   }
 324 
 325   public void visitInnerClasses(InnerClasses ic) {
 326     stack.push(ic);
 327     ic.accept(visitor);
 328 
 329     InnerClass[] ics = ic.getInnerClasses();
 330     for(int i=0; i < ics.length; i++)
 331       ics[i].accept(this);
 332     stack.pop();
 333   }
 334 
 335   public void visitInnerClass(InnerClass inner) {
 336     stack.push(inner);
 337     inner.accept(visitor);
 338     stack.pop();
 339   }
 340 
 341   public void visitDeprecated(Deprecated attribute) {
 342     stack.push(attribute);
 343     attribute.accept(visitor);
 344     stack.pop();
 345   }
 346 
 347   public void visitSignature(Signature attribute) {
 348     stack.push(attribute);
 349     attribute.accept(visitor);
 350     stack.pop();
 351   }
 352 
 353   public void visitSourceFile(SourceFile attribute) {
 354     stack.push(attribute);
 355     attribute.accept(visitor);
 356     stack.pop();
 357   }
 358 
 359   public void visitSynthetic(Synthetic attribute) {
 360     stack.push(attribute);
 361     attribute.accept(visitor);
 362     stack.pop();
 363   }
 364 
 365   public void visitUnknown(Unknown attribute) {
 366     stack.push(attribute);
 367     attribute.accept(visitor);
 368     stack.pop();
 369  }
 370 }