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 }