/* * Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.bcel5_2_0.classfile; import java.util.Stack; /** * Traverses a JavaClass with another Visitor object 'piggy-backed' * that is applied to all components of a JavaClass object. I.e. this * class supplies the traversal strategy, other classes can make use * of it. * * @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> */ public class DescendingVisitor implements Visitor { private JavaClass clazz; private Visitor visitor; private Stack stack = new Stack(); /** @return container of current entitity, i.e., predecessor during traversal */ public Object predecessor() { return predecessor(0); } /** * @param level nesting level, i.e., 0 returns the direct predecessor * @return container of current entitity, i.e., predecessor during traversal */ public Object predecessor( int level ) { int size = stack.size(); if ((size < 2) || (level < 0)) { return null; } else { return stack.elementAt(size - (level + 2)); // size - 1 == current } } /** @return current object */ public Object current() { return stack.peek(); } /** * @param clazz Class to traverse * @param visitor visitor object to apply to all components */ public DescendingVisitor(JavaClass clazz, Visitor visitor) { this.clazz = clazz; this.visitor = visitor; } /** * Start traversal. */ public void visit() { clazz.accept(this); } public void visitJavaClass( JavaClass _clazz ) { stack.push(_clazz); _clazz.accept(visitor); Field[] fields = _clazz.getFields(); for (int i = 0; i < fields.length; i++) { fields[i].accept(this); } Method[] methods = _clazz.getMethods(); for (int i = 0; i < methods.length; i++) { methods[i].accept(this); } Attribute[] attributes = _clazz.getAttributes(); for (int i = 0; i < attributes.length; i++) { attributes[i].accept(this); } _clazz.getConstantPool().accept(this); stack.pop(); } public void visitField( Field field ) { stack.push(field); field.accept(visitor); Attribute[] attributes = field.getAttributes(); for (int i = 0; i < attributes.length; i++) { attributes[i].accept(this); } stack.pop(); } public void visitConstantValue( ConstantValue cv ) { stack.push(cv); cv.accept(visitor); stack.pop(); } public void visitMethod( Method method ) { stack.push(method); method.accept(visitor); Attribute[] attributes = method.getAttributes(); for (int i = 0; i < attributes.length; i++) { attributes[i].accept(this); } stack.pop(); } public void visitExceptionTable( ExceptionTable table ) { stack.push(table); table.accept(visitor); stack.pop(); } public void visitCode( Code code ) { stack.push(code); code.accept(visitor); CodeException[] table = code.getExceptionTable(); for (int i = 0; i < table.length; i++) { table[i].accept(this); } Attribute[] attributes = code.getAttributes(); for (int i = 0; i < attributes.length; i++) { attributes[i].accept(this); } stack.pop(); } public void visitCodeException( CodeException ce ) { stack.push(ce); ce.accept(visitor); stack.pop(); } public void visitLineNumberTable( LineNumberTable table ) { stack.push(table); table.accept(visitor); LineNumber[] numbers = table.getLineNumberTable(); for (int i = 0; i < numbers.length; i++) { numbers[i].accept(this); } stack.pop(); } public void visitLineNumber( LineNumber number ) { stack.push(number); number.accept(visitor); stack.pop(); } public void visitLocalVariableTable( LocalVariableTable table ) { stack.push(table); table.accept(visitor); LocalVariable[] vars = table.getLocalVariableTable(); for (int i = 0; i < vars.length; i++) { vars[i].accept(this); } stack.pop(); } public void visitStackMap( StackMap table ) { stack.push(table); table.accept(visitor); StackMapEntry[] vars = table.getStackMap(); for (int i = 0; i < vars.length; i++) { vars[i].accept(this); } stack.pop(); } public void visitStackMapEntry( StackMapEntry var ) { stack.push(var); var.accept(visitor); stack.pop(); } public void visitLocalVariable( LocalVariable var ) { stack.push(var); var.accept(visitor); stack.pop(); } public void visitConstantPool( ConstantPool cp ) { stack.push(cp); cp.accept(visitor); Constant[] constants = cp.getConstantPool(); for (int i = 1; i < constants.length; i++) { if (constants[i] != null) { constants[i].accept(this); } } stack.pop(); } public void visitConstantClass( ConstantClass constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantDouble( ConstantDouble constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantFieldref( ConstantFieldref constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantFloat( ConstantFloat constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantInteger( ConstantInteger constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantLong( ConstantLong constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantMethodref( ConstantMethodref constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantNameAndType( ConstantNameAndType constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantString( ConstantString constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitConstantUtf8( ConstantUtf8 constant ) { stack.push(constant); constant.accept(visitor); stack.pop(); } public void visitInnerClasses( InnerClasses ic ) { stack.push(ic); ic.accept(visitor); InnerClass[] ics = ic.getInnerClasses(); for (int i = 0; i < ics.length; i++) { ics[i].accept(this); } stack.pop(); } public void visitInnerClass( InnerClass inner ) { stack.push(inner); inner.accept(visitor); stack.pop(); } public void visitDeprecated( Deprecated attribute ) { stack.push(attribute); attribute.accept(visitor); stack.pop(); } public void visitSignature( Signature attribute ) { stack.push(attribute); attribute.accept(visitor); stack.pop(); } public void visitSourceFile( SourceFile attribute ) { stack.push(attribute); attribute.accept(visitor); stack.pop(); } public void visitSynthetic( Synthetic attribute ) { stack.push(attribute); attribute.accept(visitor); stack.pop(); } public void visitUnknown( Unknown attribute ) { stack.push(attribute); attribute.accept(visitor); stack.pop(); } }