Import a a package renamed Jakarta BCEL trunk to do the annotation scanning. There...
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 4 Dec 2009 17:49:49 +0000 (17:49 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 4 Dec 2009 17:49:49 +0000 (17:49 +0000)
This was done as an svn copy so future updates should be simple via svn merge.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@887296 13f79535-47bb-0310-9956-ffa450edef68

319 files changed:
java/org/apache/tomcat/util/bcel/Constants.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/ExceptionConstants.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/Repository.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/AccessFlags.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/AnnotationDefault.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/AnnotationElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/AnnotationEntry.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Annotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ArrayElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Attribute.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/AttributeReader.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ClassElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ClassFormatException.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ClassParser.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Code.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/CodeException.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Constant.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantCP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantClass.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantDouble.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantFieldref.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantFloat.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantInteger.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantInterfaceMethodref.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantLong.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantMethodref.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantNameAndType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantObject.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantPool.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantString.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantUtf8.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ConstantValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Deprecated.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/DescendingVisitor.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ElementValuePair.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/EmptyVisitor.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/EnclosingMethod.java [new file with mode: 0755]
java/org/apache/tomcat/util/bcel/classfile/EnumElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ExceptionTable.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Field.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/FieldOrMethod.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/InnerClass.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/InnerClasses.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/JavaClass.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/LineNumber.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/LineNumberTable.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/LocalVariable.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/LocalVariableTable.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/LocalVariableTypeTable.java [new file with mode: 0755]
java/org/apache/tomcat/util/bcel/classfile/Method.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Node.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/PMGClass.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotationEntry.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleAnnotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleParameterAnnotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleAnnotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleParameterAnnotations.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Signature.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/SimpleElementValue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/SourceFile.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/StackMap.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/StackMapEntry.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/StackMapTable.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/StackMapTableEntry.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/StackMapType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Synthetic.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Unknown.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Utility.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/Visitor.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/classfile/package.html [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/AALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/AASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ACONST_NULL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ANEWARRAY.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ARETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ARRAYLENGTH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ATHROW.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/AllocationInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/AnnotationElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/AnnotationEntryGen.java [new file with mode: 0755]
java/org/apache/tomcat/util/bcel/generic/ArithmeticInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ArrayElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ArrayInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ArrayType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BIPUSH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BREAKPOINT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BasicType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BranchHandle.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/BranchInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CHECKCAST.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CPInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ClassElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ClassGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ClassGenException.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ClassObserver.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CodeExceptionGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/CompoundInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ConstantPoolGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ConstantPushInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ConversionInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/D2F.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/D2I.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/D2L.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DADD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DCMPG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DCMPL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DCONST.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DDIV.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DLOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DMUL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DNEG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DREM.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DRETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DSTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DSUB.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP2.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP2_X1.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP2_X2.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP_X1.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/DUP_X2.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ElementValuePairGen.java [new file with mode: 0755]
java/org/apache/tomcat/util/bcel/generic/EmptyVisitor.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/EnumElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ExceptionThrower.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/F2D.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/F2I.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/F2L.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FADD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FCMPG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FCMPL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FCONST.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FDIV.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FLOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FMUL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FNEG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FREM.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FRETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FSTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FSUB.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FieldGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FieldGenOrMethodGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FieldInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FieldObserver.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/FieldOrMethod.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/GETFIELD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/GETSTATIC.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/GOTO.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/GOTO_W.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/GotoInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2B.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2C.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2D.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2F.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2L.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/I2S.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IADD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IAND.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ICONST.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IDIV.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFEQ.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFGE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFGT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFLE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFLT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFNE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFNONNULL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IFNULL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ACMPEQ.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ACMPNE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPEQ.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPGE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPGT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPLE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPLT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IF_ICMPNE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IINC.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ILOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IMPDEP1.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IMPDEP2.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IMUL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INEG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INSTANCEOF.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INVOKEINTERFACE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INVOKESPECIAL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INVOKESTATIC.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/INVOKEVIRTUAL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IOR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IREM.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IRETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ISHL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ISHR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ISTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ISUB.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IUSHR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IXOR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IfInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/IndexedInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/Instruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionComparator.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionConstants.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionFactory.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionHandle.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionList.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionListObserver.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InstructionTargeter.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/InvokeInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/JSR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/JSR_W.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/JsrInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/L2D.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/L2F.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/L2I.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LADD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LAND.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LCMP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LCONST.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LDC.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LDC2_W.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LDC_W.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LDIV.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LLOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LMUL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LNEG.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LOOKUPSWITCH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LOR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LREM.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LRETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LSHL.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LSHR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LSTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LSUB.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LUSHR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LXOR.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LineNumberGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LoadClass.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LoadInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LocalVariableGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/LocalVariableInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/MONITORENTER.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/MONITOREXIT.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/MULTIANEWARRAY.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/MethodGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/MethodObserver.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/NEW.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/NEWARRAY.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/NOP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/NamedAndTyped.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ObjectType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/POP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/POP2.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/PUSH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/PUTFIELD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/PUTSTATIC.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/PopInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/PushInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/RET.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/RETURN.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ReferenceType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ReturnInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/ReturnaddressType.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SALOAD.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SASTORE.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SIPUSH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SWAP.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SWITCH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/Select.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/SimpleElementValueGen.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/StackConsumer.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/StackInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/StackProducer.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/StoreInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/TABLESWITCH.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/TargetLostException.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/Type.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/TypedInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/UnconditionalBranch.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/VariableLengthInstruction.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/Visitor.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/generic/package.html [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/package.html [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/AttributeHTML.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/BCELComparator.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/BCELFactory.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/BCELifier.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ByteSequence.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/Class2HTML.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassLoader.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassLoaderRepository.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassPath.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassQueue.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassSet.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassStack.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ClassVector.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/CodeHTML.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/ConstantHTML.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/InstructionFinder.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/JavaWrapper.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/MethodHTML.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/Repository.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/SyntheticRepository.java [new file with mode: 0644]
java/org/apache/tomcat/util/bcel/util/package.html [new file with mode: 0644]

diff --git a/java/org/apache/tomcat/util/bcel/Constants.java b/java/org/apache/tomcat/util/bcel/Constants.java
new file mode 100644 (file)
index 0000000..5a02973
--- /dev/null
@@ -0,0 +1,1467 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel;
+
+/**
+ * Constants for the project, mostly defined in the JVM specification.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface Constants {
+
+  /** Major version number of class files for Java 1.1.
+   *  @see #MINOR_1_1
+   *  */
+  public final static short MAJOR_1_1 = 45;
+
+  /** Minor version number of class files for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public final static short MINOR_1_1 = 3;
+
+  /** Major version number of class files for Java 1.2.
+   *  @see #MINOR_1_2
+   *  */
+  public final static short MAJOR_1_2 = 46;
+
+  /** Minor version number of class files for Java 1.2.
+   *  @see #MAJOR_1_2
+   *  */
+  public final static short MINOR_1_2 = 0;
+
+  /** Major version number of class files for Java 1.2.
+   *  @see #MINOR_1_2
+   *  */
+  public final static short MAJOR_1_3 = 47;
+
+  /** Minor version number of class files for Java 1.3.
+   *  @see #MAJOR_1_3
+   *  */
+  public final static short MINOR_1_3 = 0;
+
+  /** Major version number of class files for Java 1.3.
+   *  @see #MINOR_1_3
+   *  */
+  public final static short MAJOR_1_4 = 48;
+
+  /** Minor version number of class files for Java 1.4.
+   *  @see #MAJOR_1_4
+   *  */
+  public final static short MINOR_1_4 = 0;
+
+  /** Major version number of class files for Java 1.4.
+   *  @see #MINOR_1_4
+   *  */
+  public final static short MAJOR_1_5 = 49;
+
+  /** Minor version number of class files for Java 1.5.
+   *  @see #MAJOR_1_5
+   *  */
+  public final static short MINOR_1_5 = 0;
+
+  /** Major version number of class files for Java 1.5.
+   *  @see #MINOR_1_5
+   *  */
+  public final static short MAJOR_1_6 = 50;
+
+  /** Minor version number of class files for Java 1.6.
+   *  @see #MAJOR_1_6
+   *  */
+  public final static short MINOR_1_6 = 0;
+
+  /** Default major version number.  Class file is for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public final static short MAJOR = MAJOR_1_1;
+
+  /** Default major version number.  Class file is for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public final static short MINOR     = MINOR_1_1;
+
+  /** Maximum value for an unsigned short.
+   */
+  public final static int MAX_SHORT = 65535; // 2^16 - 1
+
+  /** Maximum value for an unsigned byte.
+   */
+  public final static int MAX_BYTE  = 255; // 2^8 - 1
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see <a href='http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#2877'>Flag definitions for Fields in the Java Virtual Machine Specification (2nd edition).</a>
+   *  @see <a href='http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#1513'>Flag definitions for Methods in the Java Virtual Machine Specification (2nd edition).</a>
+   *  @see <a href='http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#88478'>Flag definitions for Classes in the Java Virtual Machine Specification (2nd edition).</a>
+   */
+  public final static short ACC_PUBLIC       = 0x0001;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_PRIVATE      = 0x0002;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_PROTECTED    = 0x0004;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_STATIC       = 0x0008;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_FINAL        = 0x0010;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_SYNCHRONIZED = 0x0020;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_SYPER        = 0x0020;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_VOLATILE     = 0x0040;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_BRIDGE       = 0x0040;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_TRANSIENT    = 0x0080;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_VARARGS      = 0x0080;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_NATIVE       = 0x0100;
+  
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_INTERFACE    = 0x0200;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_ABSTRACT     = 0x0400;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_STRICT       = 0x0800;
+  
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_SYNTHETIC    = 0x1000;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_ANNOTATION   = 0x2000;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_ENUM         = 0x4000;
+
+  // Applies to classes compiled by new compilers only
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short ACC_SUPER        = 0x0020;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public final static short MAX_ACC_FLAG     = ACC_ENUM;
+
+  /** The names of the access flags. */
+  public final static String[] ACCESS_NAMES = {
+    "public", "private", "protected", "static", "final", "synchronized",
+    "volatile", "transient", "native", "interface", "abstract", "strictfp",
+    "synthetic", "annotation", "enum"
+  };
+
+  /** Marks a constant pool entry as type UTF-8.  */
+  public final static byte CONSTANT_Utf8               = 1;
+
+  /** Marks a constant pool entry as type Integer.  */
+  public final static byte CONSTANT_Integer            = 3;
+
+  /** Marks a constant pool entry as type Float.  */
+  public final static byte CONSTANT_Float              = 4;
+
+  /** Marks a constant pool entry as type Long.  */
+  public final static byte CONSTANT_Long               = 5;
+
+  /** Marks a constant pool entry as type Double.  */
+  public final static byte CONSTANT_Double             = 6;
+
+  /** Marks a constant pool entry as a Class.  */
+  public final static byte CONSTANT_Class              = 7;
+
+  /** Marks a constant pool entry as a Field Reference.  */
+  public final static byte CONSTANT_Fieldref           = 9;
+
+  /** Marks a constant pool entry as type String.  */
+  public final static byte CONSTANT_String             = 8;
+
+  /** Marks a constant pool entry as a Method Reference.  */
+  public final static byte CONSTANT_Methodref          = 10;
+
+  /** Marks a constant pool entry as an Interface Method Reference.  */
+  public final static byte CONSTANT_InterfaceMethodref = 11;
+
+  /** Marks a constant pool entry as a name and type.  */
+  public final static byte CONSTANT_NameAndType        = 12;
+
+  /** The names of the types of entries in a constant pool. */
+  public final static String[] CONSTANT_NAMES = {
+    "", "CONSTANT_Utf8", "", "CONSTANT_Integer",
+    "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double",
+    "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
+    "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
+    "CONSTANT_NameAndType" };
+
+  /** The name of the static initializer, also called &quot;class
+   *  initialization method&quot; or &quot;interface initialization
+   *   method&quot;. This is &quot;&lt;clinit&gt;&quot;.
+   */
+  public final static String STATIC_INITIALIZER_NAME = "<clinit>";
+
+  /** The name of every constructor method in a class, also called
+   * &quot;instance initialization method&quot;. This is &quot;&lt;init&gt;&quot;.
+   */
+  public final static String CONSTRUCTOR_NAME = "<init>";
+
+  /** The names of the interfaces implemented by arrays */
+  public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"};
+
+  /**
+   * One of the limitations of the Java Virtual Machine.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#88659"> The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10.</a>
+   */
+  public static final int MAX_CP_ENTRIES     = 65535;
+
+  /**
+   * One of the limitations of the Java Virtual Machine.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#88659"> The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10.</a>
+   */
+  public static final int MAX_CODE_SIZE      = 65536; //bytes
+
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NOP              = 0;
+
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ACONST_NULL      = 1;
+
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_M1        = 2;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_0         = 3;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_1         = 4;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_2         = 5;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_3         = 6;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_4         = 7;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_5         = 8;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCONST_0         = 9;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCONST_1         = 10;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_0         = 11;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_1         = 12;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_2         = 13;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCONST_0         = 14;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCONST_1         = 15;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BIPUSH           = 16;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SIPUSH           = 17;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC              = 18;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC_W            = 19;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC2_W           = 20;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD            = 21;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD            = 22;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD            = 23;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD            = 24;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD            = 25;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_0          = 26;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_1          = 27;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_2          = 28;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_3          = 29;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_0          = 30;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_1          = 31;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_2          = 32;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_3          = 33;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_0          = 34;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_1          = 35;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_2          = 36;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_3          = 37;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_0          = 38;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_1          = 39;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_2          = 40;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_3          = 41;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_0          = 42;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_1          = 43;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_2          = 44;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_3          = 45;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IALOAD           = 46;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LALOAD           = 47;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FALOAD           = 48;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DALOAD           = 49;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short AALOAD           = 50;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BALOAD           = 51;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CALOAD           = 52;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SALOAD           = 53;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE           = 54;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE           = 55;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE           = 56;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE           = 57;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE           = 58;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_0         = 59;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_1         = 60;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_2         = 61;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_3         = 62;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_0         = 63;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_1         = 64;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_2         = 65;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_3         = 66;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_0         = 67;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_1         = 68;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_2         = 69;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_3         = 70;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_0         = 71;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_1         = 72;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_2         = 73;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_3         = 74;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_0         = 75;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_1         = 76;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_2         = 77;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_3         = 78;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IASTORE          = 79;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LASTORE          = 80;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FASTORE          = 81;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DASTORE          = 82;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short AASTORE          = 83;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BASTORE          = 84;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CASTORE          = 85;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SASTORE          = 86;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short POP              = 87;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short POP2             = 88;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP              = 89;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP_X1           = 90;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP_X2           = 91;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2             = 92;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2_X1          = 93;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2_X2          = 94;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SWAP             = 95;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IADD             = 96;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LADD             = 97;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FADD             = 98;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DADD             = 99;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISUB             = 100;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSUB             = 101;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSUB             = 102;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSUB             = 103;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IMUL             = 104;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LMUL             = 105;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FMUL             = 106;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DMUL             = 107;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IDIV             = 108;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDIV             = 109;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FDIV             = 110;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DDIV             = 111;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IREM             = 112;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LREM             = 113;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FREM             = 114;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DREM             = 115;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INEG             = 116;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LNEG             = 117;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FNEG             = 118;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DNEG             = 119;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISHL             = 120;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSHL             = 121;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISHR             = 122;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSHR             = 123;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IUSHR            = 124;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LUSHR            = 125;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IAND             = 126;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LAND             = 127;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IOR              = 128;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LOR              = 129;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IXOR             = 130;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LXOR             = 131;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IINC             = 132;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2L              = 133;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2F              = 134;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2D              = 135;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2I              = 136;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2F              = 137;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2D              = 138;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2I              = 139;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2L              = 140;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2D              = 141;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2I              = 142;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2L              = 143;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2F              = 144;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2B              = 145;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2BYTE         = 145; // Old notion
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2C              = 146;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2CHAR         = 146; // Old notion
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2S              = 147;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2SHORT        = 147; // Old notion
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCMP             = 148;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCMPL            = 149;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCMPG            = 150;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCMPL            = 151;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCMPG            = 152;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFEQ             = 153;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNE             = 154;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFLT             = 155;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFGE             = 156;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFGT             = 157;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFLE             = 158;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPEQ        = 159;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPNE        = 160;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPLT        = 161;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPGE        = 162;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPGT        = 163;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPLE        = 164;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ACMPEQ        = 165;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ACMPNE        = 166;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GOTO             = 167;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short JSR              = 168;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short RET              = 169;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short TABLESWITCH      = 170;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LOOKUPSWITCH     = 171;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IRETURN          = 172;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LRETURN          = 173;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FRETURN          = 174;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DRETURN          = 175;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ARETURN          = 176;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short RETURN           = 177;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GETSTATIC        = 178;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short PUTSTATIC        = 179;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GETFIELD         = 180;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short PUTFIELD         = 181;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEVIRTUAL    = 182;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKESPECIAL    = 183;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKESTATIC     = 184;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEINTERFACE  = 185;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEDYNAMIC    = 186;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NEW              = 187;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NEWARRAY         = 188;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ANEWARRAY        = 189;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ARRAYLENGTH      = 190;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ATHROW           = 191;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CHECKCAST        = 192;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INSTANCEOF       = 193;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MONITORENTER     = 194;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MONITOREXIT      = 195;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short WIDE             = 196;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MULTIANEWARRAY   = 197;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNULL           = 198;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNONNULL        = 199;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GOTO_W           = 200;
+  /** Java VM opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html">Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short JSR_W            = 201;
+
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions.doc.html#60105">Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short BREAKPOINT                = 202;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC_QUICK                 = 203;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC_W_QUICK               = 204;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC2_W_QUICK              = 205;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD_QUICK            = 206;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD_QUICK            = 207;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD2_QUICK           = 208;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD2_QUICK           = 209;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETSTATIC_QUICK           = 210;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTSTATIC_QUICK           = 211;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETSTATIC2_QUICK          = 212;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTSTATIC2_QUICK          = 213;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUAL_QUICK       = 214;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKENONVIRTUAL_QUICK    = 215;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKESUPER_QUICK         = 216;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKESTATIC_QUICK        = 217;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEINTERFACE_QUICK     = 218;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUALOBJECT_QUICK = 219;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short NEW_QUICK                 = 221;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short ANEWARRAY_QUICK           = 222;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short MULTIANEWARRAY_QUICK      = 223;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short CHECKCAST_QUICK           = 224;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INSTANCEOF_QUICK          = 225;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUAL_QUICK_W     = 226;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD_QUICK_W          = 227;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html#10673">Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ChangesAppendix.doc.html#448885">Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD_QUICK_W          = 228;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions.doc.html#60105">Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short IMPDEP1                   = 254;
+  /** JVM internal opcode.
+   * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions.doc.html#60105">Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short IMPDEP2                   = 255;
+
+  /**
+   * BCEL virtual instruction for pushing an arbitrary data type onto the stack.  Will be converted to the appropriate JVM
+   * opcode when the class is dumped.
+   */
+  public static final short PUSH             = 4711;
+  /**
+   * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH.  Will be converted to the appropriate JVM
+   * opcode when the class is dumped.
+   */
+  public static final short SWITCH           = 4712;
+
+  /** Illegal opcode. */
+  public static final short  UNDEFINED      = -1;
+  /** Illegal opcode. */
+  public static final short  UNPREDICTABLE  = -2;
+  /** Illegal opcode. */
+  public static final short  RESERVED       = -3;
+  /** Mnemonic for an illegal opcode. */
+  public static final String ILLEGAL_OPCODE = "<illegal opcode>";
+  /** Mnemonic for an illegal type. */
+  public static final String ILLEGAL_TYPE   = "<illegal type>";
+
+  /** Boolean data type. */
+  public static final byte T_BOOLEAN = 4;
+  /** Char data type. */
+  public static final byte T_CHAR    = 5;
+  /** Float data type. */
+  public static final byte T_FLOAT   = 6;
+  /** Double data type. */
+  public static final byte T_DOUBLE  = 7;
+  /** Byte data type. */
+  public static final byte T_BYTE    = 8;
+  /** Short data type. */
+  public static final byte T_SHORT   = 9;
+  /** Int data type. */
+  public static final byte T_INT     = 10;
+  /** Long data type. */
+  public static final byte T_LONG    = 11;
+
+  /** Void data type (non-standard). */
+  public static final byte T_VOID      = 12; // Non-standard
+  /** Array data type. */
+  public static final byte T_ARRAY     = 13;
+  /** Object data type. */
+  public static final byte T_OBJECT    = 14;
+  /** Reference data type (deprecated). */
+  public static final byte T_REFERENCE = 14; // Deprecated
+  /** Unknown data type. */
+  public static final byte T_UNKNOWN   = 15;
+  /** Address data type. */
+  public static final byte T_ADDRESS   = 16;
+
+  /** The primitive type names corresponding to the T_XX constants,
+   * e.g., TYPE_NAMES[T_INT] = "int"
+   */
+  public static final String[] TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "boolean", "char", "float", "double", "byte", "short", "int", "long",
+    "void", "array", "object", "unknown", "address"
+  };
+
+  /** The primitive class names corresponding to the T_XX constants,
+   * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
+   */
+  public static final String[] CLASS_TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "java.lang.Boolean", "java.lang.Character", "java.lang.Float",
+    "java.lang.Double", "java.lang.Byte", "java.lang.Short",
+    "java.lang.Integer", "java.lang.Long", "java.lang.Void",
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE,  ILLEGAL_TYPE
+  };
+
+  /** The signature characters corresponding to primitive types,
+   * e.g., SHORT_TYPE_NAMES[T_INT] = "I"
+   */
+  public static final String[] SHORT_TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "Z", "C", "F", "D", "B", "S", "I", "J",
+    "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
+  };
+
+  /**
+   * Number of byte code operands for each opcode, i.e., number of bytes after the tag byte
+   * itself.  Indexed by opcode, so NO_OF_OPERANDS[BIPUSH] = the number of operands for a bipush
+   * instruction.
+   */
+  public static final short[] NO_OF_OPERANDS = {
+    0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/,
+    0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/,
+    0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/,
+    0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/,
+    1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/,
+    1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/,
+    0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/,
+    0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/,
+    0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/,
+    0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/,
+    0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/,
+    0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/,
+    0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/,
+    1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/,
+    1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/,
+    0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/,
+    0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
+    0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/,
+    0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/,
+    0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/,
+    0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/,
+    0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/,
+    0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/,
+    0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/,
+    0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/,
+    0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/,
+    0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/,
+    0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/,
+    0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/,
+    0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/,
+    2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/,
+    0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/,
+    0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/,
+    0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/,
+    2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/,
+    2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/,
+    2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/,
+    2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/,
+    0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
+    0/*dreturn*/, 0/*areturn*/, 0/*return*/,
+    2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/,
+    2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/,
+    4/*invokeinterface*/, UNDEFINED, 2/*new*/,
+    1/*newarray*/, 2/*anewarray*/,
+    0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/,
+    2/*instanceof*/, 0/*monitorenter*/,
+    0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/,
+    2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/,
+    4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/
+  };
+
+  /**
+   * How the byte code operands are to be interpreted for each opcode.
+   * Indexed by opcode.  TYPE_OF_OPERANDS[ILOAD] = an array of shorts
+   * describing the data types for the instruction.
+   */
+  public static final short[][] TYPE_OF_OPERANDS = {
+    {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/,
+    {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/,
+    {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/,
+    {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/,
+    {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/,
+    {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/,
+    {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/,
+    {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/,
+    {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/,
+    {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/,
+    {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/,
+    {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/,
+    {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/,
+    {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/,
+    {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/,
+    {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/,
+    {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/,
+    {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/,
+    {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/,
+    {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/,
+    {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/,
+    {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/,
+    {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/,
+    {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/,
+    {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/,
+    {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/,
+    {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/,
+    {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/,
+    {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/,
+    {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/,
+    {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/,
+    {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/,
+    {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/,
+    {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/,
+    {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/,
+    {}/*i2b*/, {}/*i2c*/,{}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/,
+    {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/,
+    {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/,
+    {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/,
+    {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/,
+    {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/,
+    {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/,
+    {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/,
+    {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/,
+    {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/,
+    {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/,
+    {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/,
+    {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/,
+    {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/,
+    {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {},
+    {T_SHORT}/*new*/, {T_BYTE}/*newarray*/,
+    {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/,
+    {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/,
+    {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/,
+    {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/,
+    {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/,
+    {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}/*impdep1*/, {}/*impdep2*/
+  };
+
+  /**
+   * Names of opcodes.  Indexed by opcode.  OPCODE_NAMES[ALOAD] = "aload".
+   */ 
+  public static final String[] OPCODE_NAMES = {
+    "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1",
+    "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0",
+    "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0",
+    "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload",
+    "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2",
+    "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0",
+    "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2",
+    "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload",
+    "laload", "faload", "daload", "aaload", "baload", "caload", "saload",
+    "istore", "lstore", "fstore", "dstore", "astore", "istore_0",
+    "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1",
+    "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2",
+    "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3",
+    "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore",
+    "fastore", "dastore", "aastore", "bastore", "castore", "sastore",
+    "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1",
+    "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub",
+    "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv",
+    "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg",
+    "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr",
+    "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f",
+    "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f",
+    "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg",
+    "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle",
+    "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt",
+    "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret",
+    "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
+    "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield",
+    "putfield", "invokevirtual", "invokespecial", "invokestatic",
+    "invokeinterface", ILLEGAL_OPCODE, "new", "newarray", "anewarray",
+    "arraylength", "athrow", "checkcast", "instanceof", "monitorenter",
+    "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull",
+    "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, "impdep1", "impdep2"
+  };
+
+  /**
+   * Number of words consumed on operand stack by instructions.
+   * Indexed by opcode.  CONSUME_STACK[FALOAD] = number of words
+   * consumed from the stack by a faload instruction.
+   */ 
+  public static final int[] CONSUME_STACK = {
+    0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/,
+    0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/,
+    0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/,
+    0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/,
+    0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/,
+    0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/,
+    0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/,
+    0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/,
+    2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/,
+    1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/,
+    1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/,
+    2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/,
+    1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/,
+    1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/,
+    3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/,
+    1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/,
+    4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/,
+    2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/,
+    2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/,
+    1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/,
+    2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/,
+    1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/,
+    1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 
+    4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/,
+    1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/,
+    2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/,
+    0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/,
+    2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/,
+    UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/,
+    UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/,
+    UNPREDICTABLE/*invokestatic*/,
+    UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 0/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/,
+    1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/,
+    0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/
+  };
+
+  /**
+   * Number of words produced onto operand stack by instructions.
+   * Indexed by opcode.  CONSUME_STACK[DALOAD] = number of words
+   * consumed from the stack by a daload instruction.
+   */ 
+  public static final int[] PRODUCE_STACK = {
+    0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/,
+    1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/,
+    2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/,
+    2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/,
+    2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/,
+    1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/,
+    1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/,
+    2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/,
+    2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/,
+    0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/,
+    0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/,
+    0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
+    0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/,
+    0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/,
+    0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/,
+    0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/,
+    6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/,
+    1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/,
+    1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/,
+    1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/,
+    1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/,
+    0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/,
+    2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/,
+    1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/,
+    1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/,
+    0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/,
+    0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/,
+    0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
+    0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/,
+    UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/,
+    UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/,
+    UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 1/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/,
+    0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/,
+    0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/
+  };
+
+  /** Attributes and their corresponding names.
+   */
+  public static final byte ATTR_UNKNOWN                                        = -1;
+  public static final byte ATTR_SOURCE_FILE                                    = 0;
+  public static final byte ATTR_CONSTANT_VALUE                                 = 1;
+  public static final byte ATTR_CODE                                           = 2;
+  public static final byte ATTR_EXCEPTIONS                                     = 3;
+  public static final byte ATTR_LINE_NUMBER_TABLE                              = 4;
+  public static final byte ATTR_LOCAL_VARIABLE_TABLE                           = 5;
+  public static final byte ATTR_INNER_CLASSES                                  = 6;
+  public static final byte ATTR_SYNTHETIC                                      = 7;
+  public static final byte ATTR_DEPRECATED                                     = 8;
+  public static final byte ATTR_PMG                                            = 9;
+  public static final byte ATTR_SIGNATURE                                      = 10;
+  public static final byte ATTR_STACK_MAP                                      = 11;
+  public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS                            = 12;
+  public static final byte ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS                          = 13;
+  public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS  = 14;
+  public static final byte ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS = 15;
+  public static final byte ATTR_ANNOTATION_DEFAULT                      = 16;
+  public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE               = 17;
+  public static final byte ATTR_ENCLOSING_METHOD                       = 18;
+  public static final byte ATTR_STACK_MAP_TABLE                         = 19;
+
+  public static final short KNOWN_ATTRIBUTES = 20;
+
+  // TOFO: FIXXXXX
+  public static final String[] ATTRIBUTE_NAMES = {
+    "SourceFile", "ConstantValue", "Code", "Exceptions",
+    "LineNumberTable", "LocalVariableTable",
+    "InnerClasses", "Synthetic", "Deprecated",
+    "PMGClass", "Signature", "StackMap", 
+    "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations",
+    "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations",
+    "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable"
+  };
+
+  /** Constants used in the StackMap attribute.
+   */
+  public static final byte ITEM_Bogus      = 0;
+  public static final byte ITEM_Integer    = 1;
+  public static final byte ITEM_Float      = 2;
+  public static final byte ITEM_Double     = 3;
+  public static final byte ITEM_Long       = 4;
+  public static final byte ITEM_Null       = 5;
+  public static final byte ITEM_InitObject = 6;
+  public static final byte ITEM_Object     = 7;
+  public static final byte ITEM_NewObject  = 8;
+
+  public static final String[] ITEM_NAMES = {
+    "Bogus", "Integer", "Float", "Double", "Long",
+    "Null", "InitObject", "Object", "NewObject" 
+  };
+  
+  /** Constants used to identify StackMapEntry types.
+   * 
+   * For those types which can specify a range, the 
+   * constant names the lowest value.
+   */
+  public static final int SAME_FRAME = 0; 
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; 
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; 
+  public static final int CHOP_FRAME = 248; 
+  public static final int SAME_FRAME_EXTENDED = 251; 
+  public static final int APPEND_FRAME = 252; 
+  public static final int FULL_FRAME = 255; 
+  
+  /** Constants that define the maximum value of 
+   * those constants which store ranges. */
+  
+  public static final int SAME_FRAME_MAX = 63;
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127;
+  public static final int CHOP_FRAME_MAX = 250;
+  public static final int APPEND_FRAME_MAX = 254;
+}
diff --git a/java/org/apache/tomcat/util/bcel/ExceptionConstants.java b/java/org/apache/tomcat/util/bcel/ExceptionConstants.java
new file mode 100644 (file)
index 0000000..c399550
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel;
+
+/**
+ * Exception constants.
+ *
+ * @version $Id$
+ * @author  E. Haase
+ */
+public interface ExceptionConstants {
+
+    /** The mother of all exceptions
+     */
+    public static final Class THROWABLE = Throwable.class;
+    /** Super class of any run-time exception
+     */
+    public static final Class RUNTIME_EXCEPTION = RuntimeException.class;
+    /** Super class of any linking exception (aka Linkage Error)
+     */
+    public static final Class LINKING_EXCEPTION = LinkageError.class;
+    /** Linking Exceptions
+     */
+    public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class;
+    public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class;
+    public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class;
+    public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class;
+    public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class;
+    public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class;
+    public static final Class INSTANTIATION_ERROR = InstantiationError.class;
+    public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class;
+    public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class;
+    public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class;
+    public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class;
+    public static final Class VERIFY_ERROR = VerifyError.class;
+    /* UnsupportedClassVersionError is new in JDK 1.2 */
+    //public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class;
+    /** Run-Time Exceptions 
+     */
+    public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class;
+    public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class;
+    public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class;
+    public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class;
+    public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class;
+    public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class;
+    /** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual
+     * Machine Specification 
+     */
+    public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = {
+            NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR,
+            EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR
+    }; // Chapter 5.1
+    public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = {
+            NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR
+    }; // Chapter 5.2
+    public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below)
+    public static final Class[] EXCS_STRING_RESOLUTION = new Class[0];
+    // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.)
+    public static final Class[] EXCS_ARRAY_EXCEPTION = {
+            NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION
+    };
+}
diff --git a/java/org/apache/tomcat/util/bcel/Repository.java b/java/org/apache/tomcat/util/bcel/Repository.java
new file mode 100644 (file)
index 0000000..6719a36
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel;
+
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+import org.apache.tomcat.util.bcel.util.ClassPath;
+import org.apache.tomcat.util.bcel.util.SyntheticRepository;
+
+/**
+ * The repository maintains informations about class interdependencies, e.g.,
+ * whether a class is a sub-class of another. Delegates actual class loading
+ * to SyntheticRepository with current class path by default.
+ *
+ * @see org.apache.tomcat.util.bcel.util.Repository
+ * @see org.apache.tomcat.util.bcel.util.SyntheticRepository
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class Repository {
+
+    private static org.apache.tomcat.util.bcel.util.Repository _repository = SyntheticRepository.getInstance();
+
+
+    /** @return currently used repository instance
+     */
+    public static org.apache.tomcat.util.bcel.util.Repository getRepository() {
+        return _repository;
+    }
+
+
+    /** Set repository instance to be used for class loading
+     */
+    public static void setRepository( org.apache.tomcat.util.bcel.util.Repository rep ) {
+        _repository = rep;
+    }
+
+
+    /** Lookup class somewhere found on your CLASSPATH, or whereever the
+     * repository instance looks for it.
+     *
+     * @return class object for given fully qualified class name
+     * @throws ClassNotFoundException if the class could not be found or
+     * parsed correctly
+     */
+    public static JavaClass lookupClass( String class_name ) throws ClassNotFoundException {
+        return _repository.loadClass(class_name);
+    }
+
+
+    /**
+     * Try to find class source using the internal repository instance.
+     * @see Class
+     * @return JavaClass object for given runtime class
+     * @throws ClassNotFoundException if the class could not be found or
+     * parsed correctly
+     */
+    public static JavaClass lookupClass( Class clazz ) throws ClassNotFoundException {
+        return _repository.loadClass(clazz);
+    }
+
+
+    /**
+     * @return class file object for given Java class by looking on the
+     *  system class path; returns null if the class file can't be
+     *  found
+     */
+    public static ClassPath.ClassFile lookupClassFile( String class_name ) {
+        try {
+            ClassPath path = _repository.getClassPath();
+            if (path == null) {
+                return null;
+            }
+            return path.getClassFile(class_name);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+
+    /** Clear the repository.
+     */
+    public static void clearCache() {
+        _repository.clear();
+    }
+
+
+    /**
+     * Add clazz to repository if there isn't an equally named class already in there.
+     *
+     * @return old entry in repository
+     */
+    public static JavaClass addClass( JavaClass clazz ) {
+        JavaClass old = _repository.findClass(clazz.getClassName());
+        _repository.storeClass(clazz);
+        return old;
+    }
+
+
+    /**
+     * Remove class with given (fully qualified) name from repository.
+     */
+    public static void removeClass( String clazz ) {
+        _repository.removeClass(_repository.findClass(clazz));
+    }
+
+
+    /**
+     * Remove given class from repository.
+     */
+    public static void removeClass( JavaClass clazz ) {
+        _repository.removeClass(clazz);
+    }
+
+
+    /**
+     * @return list of super classes of clazz in ascending order, i.e.,
+     * Object is always the last element
+     * @throws ClassNotFoundException if any of the superclasses can't be found
+     */
+    public static JavaClass[] getSuperClasses( JavaClass clazz ) throws ClassNotFoundException {
+        return clazz.getSuperClasses();
+    }
+
+
+    /**
+     * @return list of super classes of clazz in ascending order, i.e.,
+     * Object is always the last element.
+     * @throws ClassNotFoundException if the named class or any of its
+     *  superclasses can't be found
+     */
+    public static JavaClass[] getSuperClasses( String class_name ) throws ClassNotFoundException {
+        JavaClass jc = lookupClass(class_name);
+        return getSuperClasses(jc);
+    }
+
+
+    /**
+     * @return all interfaces implemented by class and its super
+     * classes and the interfaces that those interfaces extend, and so on.
+     * (Some people call this a transitive hull).
+     * @throws ClassNotFoundException if any of the class's
+     *  superclasses or superinterfaces can't be found
+     */
+    public static JavaClass[] getInterfaces( JavaClass clazz ) throws ClassNotFoundException {
+        return clazz.getAllInterfaces();
+    }
+
+
+    /**
+     * @return all interfaces implemented by class and its super
+     * classes and the interfaces that extend those interfaces, and so on
+     * @throws ClassNotFoundException if the named class can't be found,
+     *   or if any of its superclasses or superinterfaces can't be found
+     */
+    public static JavaClass[] getInterfaces( String class_name ) throws ClassNotFoundException {
+        return getInterfaces(lookupClass(class_name));
+    }
+
+
+    /**
+     * Equivalent to runtime "instanceof" operator.
+     * @return true, if clazz is an instance of super_class
+     * @throws ClassNotFoundException if any superclasses or superinterfaces
+     *   of clazz can't be found
+     */
+    public static boolean instanceOf( JavaClass clazz, JavaClass super_class )
+            throws ClassNotFoundException {
+        return clazz.instanceOf(super_class);
+    }
+
+
+    /**
+     * @return true, if clazz is an instance of super_class
+     * @throws ClassNotFoundException if either clazz or super_class
+     *   can't be found
+     */
+    public static boolean instanceOf( String clazz, String super_class )
+            throws ClassNotFoundException {
+        return instanceOf(lookupClass(clazz), lookupClass(super_class));
+    }
+
+
+    /**
+     * @return true, if clazz is an instance of super_class
+     * @throws ClassNotFoundException if super_class can't be found
+     */
+    public static boolean instanceOf( JavaClass clazz, String super_class )
+            throws ClassNotFoundException {
+        return instanceOf(clazz, lookupClass(super_class));
+    }
+
+
+    /**
+     * @return true, if clazz is an instance of super_class
+     * @throws ClassNotFoundException if clazz can't be found
+     */
+    public static boolean instanceOf( String clazz, JavaClass super_class )
+            throws ClassNotFoundException {
+        return instanceOf(lookupClass(clazz), super_class);
+    }
+
+
+    /**
+     * @return true, if clazz is an implementation of interface inter
+     * @throws ClassNotFoundException if any superclasses or superinterfaces
+     *   of clazz can't be found
+     */
+    public static boolean implementationOf( JavaClass clazz, JavaClass inter )
+            throws ClassNotFoundException {
+        return clazz.implementationOf(inter);
+    }
+
+
+    /**
+     * @return true, if clazz is an implementation of interface inter
+     * @throws ClassNotFoundException if clazz, inter, or any superclasses
+     *   or superinterfaces of clazz can't be found
+     */
+    public static boolean implementationOf( String clazz, String inter )
+            throws ClassNotFoundException {
+        return implementationOf(lookupClass(clazz), lookupClass(inter));
+    }
+
+
+    /**
+     * @return true, if clazz is an implementation of interface inter
+     * @throws ClassNotFoundException if inter or any superclasses
+     *   or superinterfaces of clazz can't be found
+     */
+    public static boolean implementationOf( JavaClass clazz, String inter )
+            throws ClassNotFoundException {
+        return implementationOf(clazz, lookupClass(inter));
+    }
+
+
+    /**
+     * @return true, if clazz is an implementation of interface inter
+     * @throws ClassNotFoundException if clazz or any superclasses or
+     *   superinterfaces of clazz can't be found
+     */
+    public static boolean implementationOf( String clazz, JavaClass inter )
+            throws ClassNotFoundException {
+        return implementationOf(lookupClass(clazz), inter);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/AccessFlags.java b/java/org/apache/tomcat/util/bcel/classfile/AccessFlags.java
new file mode 100644 (file)
index 0000000..694cafe
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * Super class for all objects that have modifiers like private, final, ...
+ * I.e. classes, fields, and methods.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class AccessFlags implements java.io.Serializable {
+
+    protected int access_flags;
+
+
+    public AccessFlags() {
+    }
+
+
+    /**
+     * @param a inital access flags
+     */
+    public AccessFlags(int a) {
+        access_flags = a;
+    }
+
+
+    /** 
+     * @return Access flags of the object aka. "modifiers".
+     */
+    public final int getAccessFlags() {
+        return access_flags;
+    }
+
+
+    /** 
+     * @return Access flags of the object aka. "modifiers".
+     */
+    public final int getModifiers() {
+        return access_flags;
+    }
+
+
+    /** Set access flags aka "modifiers".
+     * @param access_flags Access flags of the object. 
+     */
+    public final void setAccessFlags( int access_flags ) {
+        this.access_flags = access_flags;
+    }
+
+
+    /** Set access flags aka "modifiers".
+     * @param access_flags Access flags of the object. 
+     */
+    public final void setModifiers( int access_flags ) {
+        setAccessFlags(access_flags);
+    }
+
+
+    private final void setFlag( int flag, boolean set ) {
+        if ((access_flags & flag) != 0) { // Flag is set already
+            if (!set) {
+                access_flags ^= flag;
+            }
+        } else { // Flag not set
+            if (set) {
+                access_flags |= flag;
+            }
+        }
+    }
+
+
+    public final void isPublic( boolean flag ) {
+        setFlag(Constants.ACC_PUBLIC, flag);
+    }
+
+
+    public final boolean isPublic() {
+        return (access_flags & Constants.ACC_PUBLIC) != 0;
+    }
+
+
+    public final void isPrivate( boolean flag ) {
+        setFlag(Constants.ACC_PRIVATE, flag);
+    }
+
+
+    public final boolean isPrivate() {
+        return (access_flags & Constants.ACC_PRIVATE) != 0;
+    }
+
+
+    public final void isProtected( boolean flag ) {
+        setFlag(Constants.ACC_PROTECTED, flag);
+    }
+
+
+    public final boolean isProtected() {
+        return (access_flags & Constants.ACC_PROTECTED) != 0;
+    }
+
+
+    public final void isStatic( boolean flag ) {
+        setFlag(Constants.ACC_STATIC, flag);
+    }
+
+
+    public final boolean isStatic() {
+        return (access_flags & Constants.ACC_STATIC) != 0;
+    }
+
+
+    public final void isFinal( boolean flag ) {
+        setFlag(Constants.ACC_FINAL, flag);
+    }
+
+
+    public final boolean isFinal() {
+        return (access_flags & Constants.ACC_FINAL) != 0;
+    }
+
+
+    public final void isSynchronized( boolean flag ) {
+        setFlag(Constants.ACC_SYNCHRONIZED, flag);
+    }
+
+
+    public final boolean isSynchronized() {
+        return (access_flags & Constants.ACC_SYNCHRONIZED) != 0;
+    }
+
+
+    public final void isVolatile( boolean flag ) {
+        setFlag(Constants.ACC_VOLATILE, flag);
+    }
+
+
+    public final boolean isVolatile() {
+        return (access_flags & Constants.ACC_VOLATILE) != 0;
+    }
+
+
+    public final void isTransient( boolean flag ) {
+        setFlag(Constants.ACC_TRANSIENT, flag);
+    }
+
+
+    public final boolean isTransient() {
+        return (access_flags & Constants.ACC_TRANSIENT) != 0;
+    }
+
+
+    public final void isNative( boolean flag ) {
+        setFlag(Constants.ACC_NATIVE, flag);
+    }
+
+
+    public final boolean isNative() {
+        return (access_flags & Constants.ACC_NATIVE) != 0;
+    }
+
+
+    public final void isInterface( boolean flag ) {
+        setFlag(Constants.ACC_INTERFACE, flag);
+    }
+
+
+    public final boolean isInterface() {
+        return (access_flags & Constants.ACC_INTERFACE) != 0;
+    }
+
+
+    public final void isAbstract( boolean flag ) {
+        setFlag(Constants.ACC_ABSTRACT, flag);
+    }
+
+
+    public final boolean isAbstract() {
+        return (access_flags & Constants.ACC_ABSTRACT) != 0;
+    }
+
+
+    public final void isStrictfp( boolean flag ) {
+        setFlag(Constants.ACC_STRICT, flag);
+    }
+
+
+    public final boolean isStrictfp() {
+        return (access_flags & Constants.ACC_STRICT) != 0;
+    }
+
+
+    public final void isSynthetic( boolean flag ) {
+        setFlag(Constants.ACC_SYNTHETIC, flag);
+    }
+
+
+    public final boolean isSynthetic() {
+        return (access_flags & Constants.ACC_SYNTHETIC) != 0;
+    }
+
+
+    public final void isAnnotation( boolean flag ) {
+        setFlag(Constants.ACC_ANNOTATION, flag);
+    }
+
+
+    public final boolean isAnnotation() {
+        return (access_flags & Constants.ACC_ANNOTATION) != 0;
+    }
+
+
+    public final void isEnum( boolean flag ) {
+        setFlag(Constants.ACC_ENUM, flag);
+    }
+
+
+    public final boolean isEnum() {
+        return (access_flags & Constants.ACC_ENUM) != 0;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/AnnotationDefault.java b/java/org/apache/tomcat/util/bcel/classfile/AnnotationDefault.java
new file mode 100644 (file)
index 0000000..b70b787
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents the default value of a annotation for a method info
+ * 
+ * @version $Id: AnnotationDefault 1 2005-02-13 03:15:08Z dbrosius $
+ * @author <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class AnnotationDefault extends Attribute
+{
+       ElementValue default_value;
+
+       /**
+        * @param annotation_type
+        *            the subclass type of the annotation
+        * @param name_index
+        *            Index pointing to the name <em>Code</em>
+        * @param length
+        *            Content length in bytes
+        * @param file
+        *            Input stream
+        * @param constant_pool
+        *            Array of constants
+        */
+       public AnnotationDefault(int name_index, int length,
+                       DataInputStream file, ConstantPool constant_pool)
+                       throws IOException
+       {
+               this(name_index, length, (ElementValue) null,
+                               constant_pool);
+               default_value = ElementValue.readElementValue(file, constant_pool);
+       }
+
+       /**
+        * @param annotation_type
+        *            the subclass type of the annotation
+        * @param name_index
+        *            Index pointing to the name <em>Code</em>
+        * @param length
+        *            Content length in bytes
+        * @param defaultValue
+        *            the annotation's default value
+        * @param constant_pool
+        *            Array of constants
+        */
+       public AnnotationDefault(int name_index, int length,
+                       ElementValue defaultValue, ConstantPool constant_pool)
+       {
+               super(Constants.ATTR_ANNOTATION_DEFAULT, name_index, length, constant_pool);
+               setDefaultValue(defaultValue);
+       }
+
+       /**
+        * Called by objects that are traversing the nodes of the tree implicitely
+        * defined by the contents of a Java class. I.e., the hierarchy of methods,
+        * fields, attributes, etc. spawns a tree of objects.
+        * 
+        * @param v
+        *            Visitor object
+        */
+       public void accept(Visitor v)
+       {
+               // v.visitAnnotationDefault(this);
+       }
+
+       /**
+        * @param defaultValue
+        *            the default value of this methodinfo's annotation
+        */
+       public final void setDefaultValue(ElementValue defaultValue)
+       {
+               default_value = defaultValue;
+       }
+
+       /**
+        * @return the default value
+        */
+       public final ElementValue getDefaultValue()
+       {
+               return default_value;
+       }
+
+       public Attribute copy(ConstantPool _constant_pool)
+       {
+               throw new RuntimeException("Not implemented yet!");
+       }
+
+    public final void dump(DataOutputStream dos) throws IOException
+    {
+      super.dump(dos);
+      default_value.dump(dos);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/AnnotationElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/AnnotationElementValue.java
new file mode 100644 (file)
index 0000000..b27f450
--- /dev/null
@@ -0,0 +1,43 @@
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class AnnotationElementValue extends ElementValue
+{
+       // For annotation element values, this is the annotation
+       private AnnotationEntry annotationEntry;
+
+       public AnnotationElementValue(int type, AnnotationEntry annotationEntry,
+                       ConstantPool cpool)
+       {
+               super(type, cpool);
+               if (type != ANNOTATION)
+                       throw new RuntimeException(
+                                       "Only element values of type annotation can be built with this ctor - type specified: " + type);
+               this.annotationEntry = annotationEntry;
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ANNOTATION == '@')
+               annotationEntry.dump(dos);
+       }
+
+       public String stringifyValue()
+       {
+               StringBuffer sb = new StringBuffer();
+               sb.append(annotationEntry.toString());
+               return sb.toString();
+       }
+
+       public String toString()
+       {
+               return stringifyValue();
+       }
+
+       public AnnotationEntry getAnnotationEntry()
+       {
+               return annotationEntry;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/AnnotationEntry.java b/java/org/apache/tomcat/util/bcel/classfile/AnnotationEntry.java
new file mode 100644 (file)
index 0000000..81bd934
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents one annotation in the annotation table
+ * 
+ * @version $Id: AnnotationEntry
+ * @author  <A HREF="mailto:dbrosius@mebigfatguy.com">D. Brosius</A>
+ * @since 5.3
+ */
+public class AnnotationEntry implements Node, Constants, Serializable {
+
+    private int type_index;
+    private int num_element_value_pairs;
+    private List element_value_pairs;
+    private ConstantPool constant_pool;
+    private boolean isRuntimeVisible;
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     */
+    public AnnotationEntry(int type_index, ConstantPool constant_pool, boolean isRuntimeVisible) {
+        this.type_index = type_index;
+        
+        this.constant_pool = constant_pool;
+        this.isRuntimeVisible = isRuntimeVisible;
+    }
+    
+    public static AnnotationEntry read(DataInputStream file, ConstantPool constant_pool, boolean isRuntimeVisible) throws IOException 
+    {
+       AnnotationEntry annotationEntry = new AnnotationEntry(file.readUnsignedShort(), constant_pool, isRuntimeVisible);
+       annotationEntry.num_element_value_pairs = (file.readUnsignedShort());
+       annotationEntry.element_value_pairs = new ArrayList();
+        for (int i = 0; i < annotationEntry.num_element_value_pairs; i++) {
+               annotationEntry.element_value_pairs.add(new ElementValuePair(file.readUnsignedShort(), ElementValue.readElementValue(file, constant_pool), constant_pool));
+        }
+        return annotationEntry;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        //         v.visitAnnotationEntry(this);
+    }
+
+
+    /**
+     * @return the annotation type name
+     */
+    public String getAnnotationType() {
+        ConstantUtf8 c;
+        c = (ConstantUtf8) constant_pool.getConstant(type_index, CONSTANT_Utf8);
+        return c.getBytes();
+    }
+    
+    /**
+     * @return the annotation type index
+     */
+    public int getAnnotationTypeIndex()
+    {
+       return type_index;
+    }
+
+
+    /**
+     * @return the number of element value pairs in this annotation entry
+     */
+    public final int getNumElementValuePairs() {
+        return num_element_value_pairs;
+    }
+
+
+    /**
+     * @return the element value pairs in this annotation entry
+     */
+    public ElementValuePair[] getElementValuePairs() {
+       // TOFO return List
+        return (ElementValuePair[]) element_value_pairs.toArray(new ElementValuePair[element_value_pairs.size()]);
+    }
+
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeShort(type_index);     // u2 index of type name in cpool
+               dos.writeShort(element_value_pairs.size()); // u2 element_value pair count
+               for (int i = 0 ; i<element_value_pairs.size();i++) {
+                       ElementValuePair envp = (ElementValuePair) element_value_pairs.get(i);
+                       envp.dump(dos);
+               }
+       }
+
+
+       public boolean isRuntimeVisible()
+       {
+               return isRuntimeVisible;
+       }
+
+       public void addElementNameValuePair(ElementValuePair elementNameValuePair)
+       {
+               element_value_pairs.add(elementNameValuePair);
+       }
+
+       public String toShortString()
+       {
+               StringBuffer result = new StringBuffer();
+               result.append("@");
+               result.append(getAnnotationType());
+               if (getElementValuePairs().length > 0)
+               {
+                       result.append("(");
+                       for (int i = 0; i < getElementValuePairs().length; i++)
+                       {
+                               ElementValuePair element = getElementValuePairs()[i];
+                               result.append(element.toShortString());
+                       }
+                       result.append(")");
+               }
+               return result.toString();
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Annotations.java b/java/org/apache/tomcat/util/bcel/classfile/Annotations.java
new file mode 100644 (file)
index 0000000..214ebef
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * base class for annotations
+ * 
+ * @version $Id: Annotations
+ * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public abstract class Annotations extends Attribute {
+
+    private int annotation_table_length;
+    private AnnotationEntry[] annotation_table; // Table of annotations
+    private boolean isRuntimeVisible;
+
+
+    /**
+     * @param annotation_type the subclass type of the annotation
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     */
+    public Annotations(byte annotation_type, int name_index, int length, DataInputStream file,
+            ConstantPool constant_pool, boolean isRuntimeVisible) throws IOException {
+        this(annotation_type, name_index, length, (AnnotationEntry[]) null, constant_pool, isRuntimeVisible);
+        annotation_table_length = (file.readUnsignedShort());
+        annotation_table = new AnnotationEntry[annotation_table_length];
+        for (int i = 0; i < annotation_table_length; i++) {
+            annotation_table[i] = AnnotationEntry.read(file, constant_pool, isRuntimeVisible);
+        }
+    }
+
+
+    /**
+     * @param annotation_type the subclass type of the annotation
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param annotation_table the actual annotations
+     * @param constant_pool Array of constants
+     */
+    public Annotations(byte annotation_type, int name_index, int length,
+            AnnotationEntry[] annotation_table, ConstantPool constant_pool , boolean isRuntimeVisible) {
+        super(annotation_type, name_index, length, constant_pool);
+        setAnnotationTable(annotation_table);
+        this.isRuntimeVisible = isRuntimeVisible;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitAnnotation(this);
+    }
+
+
+    /**
+     * @param annotation_table the entries to set in this annotation
+     */
+    public final void setAnnotationTable( AnnotationEntry[] annotation_table ) {
+        this.annotation_table = annotation_table;
+        annotation_table_length = (annotation_table == null) ? 0 : annotation_table.length;
+    }
+
+
+    // TODO: update method names
+    /**
+     * @return the annotation entry table
+     */
+    /*
+    public final AnnotationEntry[] getAnnotationTable() {
+        return annotation_table;
+    }*/
+
+
+    /**
+     * returns the array of annotation entries in this annotation
+     */
+    public AnnotationEntry[] getAnnotationEntries() {
+        return annotation_table;
+    }
+
+
+    /**
+     * @return the number of annotation entries in this annotation
+     */
+    public final int getNumAnnotations() {
+        return annotation_table_length;
+    }
+    
+    public boolean isRuntimeVisible()
+    {
+       return isRuntimeVisible;
+    }
+    
+    protected void writeAnnotations(DataOutputStream dos) throws IOException
+       {
+               dos.writeShort(annotation_table_length);
+               for (int i = 0; i < annotation_table_length; i++)
+                       annotation_table[i].dump(dos);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ArrayElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/ArrayElementValue.java
new file mode 100644 (file)
index 0000000..5a3e5db
--- /dev/null
@@ -0,0 +1,67 @@
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class ArrayElementValue extends ElementValue
+{
+       // For array types, this is the array
+       private ElementValue[] evalues;
+
+       public String toString()
+       {
+               StringBuffer sb = new StringBuffer();
+               sb.append("{");
+               for (int i = 0; i < evalues.length; i++)
+               {
+                       sb.append(evalues[i].toString());
+                       if ((i + 1) < evalues.length)
+                               sb.append(",");
+               }
+               sb.append("}");
+               return sb.toString();
+       }
+
+       public ArrayElementValue(int type, ElementValue[] datums, ConstantPool cpool)
+       {
+               super(type, cpool);
+               if (type != ARRAY)
+                       throw new RuntimeException(
+                                       "Only element values of type array can be built with this ctor - type specified: " + type);
+               this.evalues = datums;
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ARRAY == '[')
+               dos.writeShort(evalues.length);
+               for (int i = 0; i < evalues.length; i++)
+               {
+                       evalues[i].dump(dos);
+               }
+       }
+
+       public String stringifyValue()
+       {
+               StringBuffer sb = new StringBuffer();
+               sb.append("[");
+               for (int i = 0; i < evalues.length; i++)
+               {
+                       sb.append(evalues[i].stringifyValue());
+                       if ((i + 1) < evalues.length)
+                               sb.append(",");
+               }
+               sb.append("]");
+               return sb.toString();
+       }
+
+       public ElementValue[] getElementValuesArray()
+       {
+               return evalues;
+       }
+
+       public int getElementValuesArraySize()
+       {
+               return evalues.length;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Attribute.java b/java/org/apache/tomcat/util/bcel/classfile/Attribute.java
new file mode 100644 (file)
index 0000000..cb01223
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+
+/**
+ * Abstract super class for <em>Attribute</em> objects. Currently the
+ * <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
+ * <em>Exceptiontable</em>, <em>LineNumberTable</em>,
+ * <em>LocalVariableTable</em>, <em>InnerClasses</em> and
+ * <em>Synthetic</em> attributes are supported. The <em>Unknown</em>
+ * attribute stands for non-standard-attributes.
+ * 
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see ConstantValue
+ * @see SourceFile
+ * @see Code
+ * @see Unknown
+ * @see ExceptionTable
+ * @see LineNumberTable
+ * @see LocalVariableTable
+ * @see InnerClasses
+ * @see Synthetic
+ * @see Deprecated
+ * @see Signature
+ */
+public abstract class Attribute implements Cloneable, Node, Serializable
+{
+       protected int name_index; // Points to attribute name in constant pool
+
+       protected int length; // Content length of attribute field
+
+       protected byte tag; // Tag to distiguish subclasses
+
+       protected ConstantPool constant_pool;
+
+       protected Attribute(byte tag, int name_index, int length,
+                       ConstantPool constant_pool)
+       {
+               this.tag = tag;
+               this.name_index = name_index;
+               this.length = length;
+               this.constant_pool = constant_pool;
+       }
+
+       /**
+        * Called by objects that are traversing the nodes of the tree implicitely
+        * defined by the contents of a Java class. I.e., the hierarchy of methods,
+        * fields, attributes, etc. spawns a tree of objects.
+        * 
+        * @param v
+        *            Visitor object
+        */
+       public abstract void accept(Visitor v);
+
+       /**
+        * Dump attribute to file stream in binary format.
+        * 
+        * @param file
+        *            Output file stream
+        * @throws IOException
+        */
+       public void dump(DataOutputStream file) throws IOException
+       {
+               file.writeShort(name_index);
+               file.writeInt(length);
+       }
+
+       private static Map readers = new HashMap();
+
+       /**
+        * Add an Attribute reader capable of parsing (user-defined) attributes
+        * named "name". You should not add readers for the standard attributes such
+        * as "LineNumberTable", because those are handled internally.
+        * 
+        * @param name
+        *            the name of the attribute as stored in the class file
+        * @param r
+        *            the reader object
+        */
+       public static void addAttributeReader(String name, AttributeReader r)
+       {
+               readers.put(name, r);
+       }
+
+       /**
+        * Remove attribute reader
+        * 
+        * @param name
+        *            the name of the attribute as stored in the class file
+        */
+       public static void removeAttributeReader(String name)
+       {
+               readers.remove(name);
+       }
+
+       /*
+        * Class method reads one attribute from the input data stream. This method
+        * must not be accessible from the outside. It is called by the Field and
+        * Method constructor methods.
+        * 
+        * @see Field
+        * @see Method @param file Input stream @param constant_pool Array of
+        *      constants @return Attribute @throws IOException @throws
+        *      ClassFormatException
+        */
+       public static final Attribute readAttribute(DataInputStream file,
+                       ConstantPool constant_pool) throws IOException,
+                       ClassFormatException
+       {
+               ConstantUtf8 c;
+               String name;
+               int name_index;
+               int length;
+               byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute
+               // Get class name from constant pool via `name_index' indirection
+               name_index = file.readUnsignedShort();
+               c = (ConstantUtf8) constant_pool.getConstant(name_index,
+                               Constants.CONSTANT_Utf8);
+               name = c.getBytes();
+               // Length of data in bytes
+               length = file.readInt();
+               // Compare strings to find known attribute
+               // System.out.println(name);
+               for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++)
+               {
+                       if (name.equals(Constants.ATTRIBUTE_NAMES[i]))
+                       {
+                               tag = i; // found!
+                               break;
+                       }
+               }
+               // Call proper constructor, depending on `tag'
+               switch (tag)
+               {
+               case Constants.ATTR_UNKNOWN:
+                       AttributeReader r = (AttributeReader) readers.get(name);
+                       if (r != null)
+                       {
+                               return r.createAttribute(name_index, length, file,
+                                               constant_pool);
+                       }
+                       return new Unknown(name_index, length, file, constant_pool);
+               case Constants.ATTR_CONSTANT_VALUE:
+                       return new ConstantValue(name_index, length, file, constant_pool);
+               case Constants.ATTR_SOURCE_FILE:
+                       return new SourceFile(name_index, length, file, constant_pool);
+               case Constants.ATTR_CODE:
+                       return new Code(name_index, length, file, constant_pool);
+               case Constants.ATTR_EXCEPTIONS:
+                       return new ExceptionTable(name_index, length, file, constant_pool);
+               case Constants.ATTR_LINE_NUMBER_TABLE:
+                       return new LineNumberTable(name_index, length, file, constant_pool);
+               case Constants.ATTR_LOCAL_VARIABLE_TABLE:
+                       return new LocalVariableTable(name_index, length, file,
+                                       constant_pool);
+               case Constants.ATTR_INNER_CLASSES:
+                       return new InnerClasses(name_index, length, file, constant_pool);
+               case Constants.ATTR_SYNTHETIC:
+                       return new Synthetic(name_index, length, file, constant_pool);
+               case Constants.ATTR_DEPRECATED:
+                       return new Deprecated(name_index, length, file, constant_pool);
+               case Constants.ATTR_PMG:
+                       return new PMGClass(name_index, length, file, constant_pool);
+               case Constants.ATTR_SIGNATURE:
+                       return new Signature(name_index, length, file, constant_pool);
+               case Constants.ATTR_STACK_MAP:
+                       return new StackMap(name_index, length, file, constant_pool);
+               case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
+                       return new RuntimeVisibleAnnotations(name_index, length, file,
+                                       constant_pool);
+               case Constants.ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS:
+                       return new RuntimeInvisibleAnnotations(name_index, length, file,
+                                       constant_pool);
+               case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS:
+                       return new RuntimeVisibleParameterAnnotations(name_index, length,
+                                       file, constant_pool);
+               case Constants.ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS:
+                       return new RuntimeInvisibleParameterAnnotations(name_index, length,
+                                       file, constant_pool);
+               case Constants.ATTR_ANNOTATION_DEFAULT:
+                       return new AnnotationDefault(name_index, length, file,
+                                       constant_pool);
+               case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE:
+                       return new LocalVariableTypeTable(name_index, length, file,
+                                       constant_pool);
+               case Constants.ATTR_ENCLOSING_METHOD:
+                       return new EnclosingMethod(name_index, length, file, constant_pool);
+               case Constants.ATTR_STACK_MAP_TABLE:
+                       return new StackMapTable(name_index, length, file, constant_pool);
+               default: // Never reached
+                       throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag);
+               }
+       }
+
+       /**
+        * @return Name of attribute
+        */
+       public String getName()
+       {
+               ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index,
+                               Constants.CONSTANT_Utf8);
+               return c.getBytes();
+       }
+
+       /**
+        * @return Length of attribute field in bytes.
+        */
+       public final int getLength()
+       {
+               return length;
+       }
+
+       /**
+        * @param length
+        *            length in bytes.
+        */
+       public final void setLength(int length)
+       {
+               this.length = length;
+       }
+
+       /**
+        * @param name_index
+        *            of attribute.
+        */
+       public final void setNameIndex(int name_index)
+       {
+               this.name_index = name_index;
+       }
+
+       /**
+        * @return Name index in constant pool of attribute name.
+        */
+       public final int getNameIndex()
+       {
+               return name_index;
+       }
+
+       /**
+        * @return Tag of attribute, i.e., its type. Value may not be altered, thus
+        *         there is no setTag() method.
+        */
+       public final byte getTag()
+       {
+               return tag;
+       }
+
+       /**
+        * @return Constant pool used by this object.
+        * @see ConstantPool
+        */
+       public final ConstantPool getConstantPool()
+       {
+               return constant_pool;
+       }
+
+       /**
+        * @param constant_pool
+        *            Constant pool to be used for this object.
+        * @see ConstantPool
+        */
+       public final void setConstantPool(ConstantPool constant_pool)
+       {
+               this.constant_pool = constant_pool;
+       }
+
+       /**
+        * Use copy() if you want to have a deep copy(), i.e., with all references
+        * copied correctly.
+        * 
+        * @return shallow copy of this attribute
+        */
+       public Object clone()
+       {
+               Object o = null;
+               try
+               {
+                       o = super.clone();
+               }
+               catch (CloneNotSupportedException e)
+               {
+                       e.printStackTrace(); // Never occurs
+               }
+               return o;
+       }
+
+       /**
+        * @return deep copy of this attribute
+        */
+       public abstract Attribute copy(ConstantPool _constant_pool);
+
+       /**
+        * @return attribute name.
+        */
+       public String toString()
+       {
+               return Constants.ATTRIBUTE_NAMES[tag];
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/AttributeReader.java b/java/org/apache/tomcat/util/bcel/classfile/AttributeReader.java
new file mode 100644 (file)
index 0000000..166c314
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/**
+ * Unknown (non-standard) attributes may be read via user-defined factory
+ * objects that can be registered with the Attribute.addAttributeReader
+ * method. These factory objects should implement this interface.
+
+ * @see Attribute
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface AttributeReader {
+
+    /**
+     When this attribute reader is added via the static method
+     Attribute.addAttributeReader, an attribute name is associated with it.
+     As the class file parser parses attributes, it will call various
+     AttributeReaders based on the name of the attributes it is
+     constructing.
+
+     @param name_index An index into the constant pool, indexing a
+     ConstantUtf8 that represents the name of the attribute.
+
+     @param length The length of the data contained in the attribute.  This
+     is written into the constant pool and should agree with what the
+     factory expects the length to be.
+
+     @param file This is the data input stream that the factory needs to read
+     its data from.
+
+     @param constant_pool This is the constant pool associated with the
+     Attribute that we are constructing.
+
+     @return The user-defined AttributeReader should take this data and use
+     it to construct an attribute.  In the case of errors, a null can be
+     returned which will cause the parsing of the class file to fail.
+
+     @see Attribute#addAttributeReader( String, AttributeReader )
+     */
+    public Attribute createAttribute( int name_index, int length, java.io.DataInputStream file,
+            ConstantPool constant_pool );
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ClassElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/ClassElementValue.java
new file mode 100644 (file)
index 0000000..f3dad0f
--- /dev/null
@@ -0,0 +1,44 @@
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+public class ClassElementValue extends ElementValue
+{
+       // For primitive types and string type, this points to the value entry in
+       // the cpool
+       // For 'class' this points to the class entry in the cpool
+       private int idx;
+
+       public ClassElementValue(int type, int idx, ConstantPool cpool)
+       {
+               super(type, cpool);
+               this.idx = idx;
+       }
+
+       public int getIndex()
+       {
+               return idx;
+       }
+
+       public String getClassString()
+       {
+               ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(idx,
+                               Constants.CONSTANT_Utf8);
+               return c.getBytes();
+       }
+
+       public String stringifyValue()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(idx,
+                               Constants.CONSTANT_Utf8);
+               return cu8.getBytes();
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 kind of value
+               dos.writeShort(idx);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ClassFormatException.java b/java/org/apache/tomcat/util/bcel/classfile/ClassFormatException.java
new file mode 100644 (file)
index 0000000..e3c4d97
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/** 
+ * Thrown when the BCEL attempts to read a class file and determines
+ * that the file is malformed or otherwise cannot be interpreted as a
+ * class file.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ClassFormatException extends RuntimeException {
+
+    public ClassFormatException() {
+        super();
+    }
+
+
+    public ClassFormatException(String s) {
+        super(s);
+    }
+    
+    public ClassFormatException(String s, Throwable initCause) {
+       super(s, initCause);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java b/java/org/apache/tomcat/util/bcel/classfile/ClassParser.java
new file mode 100644 (file)
index 0000000..e24eea4
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * Wrapper class that parses a given Java .class file. The method <A
+ * href ="#parse">parse</A> returns a <A href ="JavaClass.html">
+ * JavaClass</A> object on success. When an I/O error or an
+ * inconsistency occurs an appropiate exception is propagated back to
+ * the caller.
+ *
+ * The structure and the names comply, except for a few conveniences,
+ * exactly with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps">
+ * JVM specification 1.0</a>. See this paper for
+ * further details about the structure of a bytecode file.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ */
+public final class ClassParser {
+
+    private DataInputStream file;
+    private boolean fileOwned;
+    private String file_name;
+    private String zip_file;
+    private int class_name_index, superclass_name_index;
+    private int major, minor; // Compiler version
+    private int access_flags; // Access rights of parsed class
+    private int[] interfaces; // Names of implemented interfaces
+    private ConstantPool constant_pool; // collection of constants
+    private Field[] fields; // class fields, i.e., its variables
+    private Method[] methods; // methods defined in the class
+    private Attribute[] attributes; // attributes defined in the class
+    private boolean is_zip; // Loaded from zip file
+    private static final int BUFSIZE = 8192;
+
+
+    /**
+     * Parse class from the given stream.
+     *
+     * @param file Input stream
+     * @param file_name File name
+     */
+    public ClassParser(InputStream file, String file_name) {
+        this.file_name = file_name;
+        fileOwned = false;
+        String clazz = file.getClass().getName(); // Not a very clean solution ...
+        is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar.");
+        if (file instanceof DataInputStream) {
+            this.file = (DataInputStream) file;
+        } else {
+            this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE));
+        }
+    }
+
+
+    /** Parse class from given .class file.
+     *
+     * @param file_name file name
+     */
+    public ClassParser(String file_name) {
+        is_zip = false;
+        this.file_name = file_name;
+        fileOwned = true;
+    }
+
+
+    /** Parse class from given .class file in a ZIP-archive
+     *
+     * @param zip_file zip file name
+     * @param file_name file name
+     */
+    public ClassParser(String zip_file, String file_name) {
+        is_zip = true;
+        fileOwned = true;
+        this.zip_file = zip_file;
+        this.file_name = file_name;
+    }
+
+
+    /**
+     * Parse the given Java class file and return an object that represents
+     * the contained data, i.e., constants, methods, fields and commands.
+     * A <em>ClassFormatException</em> is raised, if the file is not a valid
+     * .class file. (This does not include verification of the byte code as it
+     * is performed by the java interpreter).
+     *
+     * @return Class object representing the parsed class file
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    public JavaClass parse() throws IOException, ClassFormatException {
+        ZipFile zip = null;
+        try {
+            if (fileOwned) {
+                if (is_zip) {
+                    zip = new ZipFile(zip_file);
+                    ZipEntry entry = zip.getEntry(file_name);
+                    file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry),
+                            BUFSIZE));
+                } else {
+                    file = new DataInputStream(new BufferedInputStream(new FileInputStream(
+                            file_name), BUFSIZE));
+                }
+            }
+            /****************** Read headers ********************************/
+            // Check magic tag of class file
+            readID();
+            // Get compiler version
+            readVersion();
+            /****************** Read constant pool and related **************/
+            // Read constant pool entries
+            readConstantPool();
+            // Get class information
+            readClassInfo();
+            // Get interface information, i.e., implemented interfaces
+            readInterfaces();
+            /****************** Read class fields and methods ***************/
+            // Read class fields, i.e., the variables of the class
+            readFields();
+            // Read class methods, i.e., the functions in the class
+            readMethods();
+            // Read class attributes
+            readAttributes();
+            // Check for unknown variables
+            //Unknown[] u = Unknown.getUnknownAttributes();
+            //for(int i=0; i < u.length; i++)
+            //  System.err.println("WARNING: " + u[i]);
+            // Everything should have been read now
+            //      if(file.available() > 0) {
+            //        int bytes = file.available();
+            //        byte[] buf = new byte[bytes];
+            //        file.read(buf);
+            //        if(!(is_zip && (buf.length == 1))) {
+            //         System.err.println("WARNING: Trailing garbage at end of " + file_name);
+            //         System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf));
+            //        }
+            //      }
+        } finally {
+            // Read everything of interest, so close the file
+            if (fileOwned) {
+               try {
+                       if (file != null) {
+                           file.close();
+                       }
+                       if (zip != null) {
+                           zip.close();
+                       }
+               } catch (IOException ioe) {
+                       //ignore close exceptions
+               }
+            }
+        }
+        // Return the information we have gathered in a new object
+        return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor,
+                access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip
+                        ? JavaClass.ZIP
+                        : JavaClass.FILE);
+    }
+
+
+    /**
+     * Read information about the attributes of the class.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readAttributes() throws IOException, ClassFormatException {
+        int attributes_count;
+        attributes_count = file.readUnsignedShort();
+        attributes = new Attribute[attributes_count];
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i] = Attribute.readAttribute(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * Read information about the class and its super class.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readClassInfo() throws IOException, ClassFormatException {
+        access_flags = file.readUnsignedShort();
+        /* Interfaces are implicitely abstract, the flag should be set
+         * according to the JVM specification.
+         */
+        if ((access_flags & Constants.ACC_INTERFACE) != 0) {
+            access_flags |= Constants.ACC_ABSTRACT;
+        }
+        if (((access_flags & Constants.ACC_ABSTRACT) != 0)
+                && ((access_flags & Constants.ACC_FINAL) != 0)) {
+            throw new ClassFormatException("Class " + file_name + " can't be both final and abstract");
+        }
+        class_name_index = file.readUnsignedShort();
+        superclass_name_index = file.readUnsignedShort();
+    }
+
+
+    /**
+     * Read constant pool entries.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readConstantPool() throws IOException, ClassFormatException {
+        constant_pool = new ConstantPool(file);
+    }
+
+
+    /**
+     * Read information about the fields of the class, i.e., its variables.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readFields() throws IOException, ClassFormatException {
+        int fields_count;
+        fields_count = file.readUnsignedShort();
+        fields = new Field[fields_count];
+        for (int i = 0; i < fields_count; i++) {
+            fields[i] = new Field(file, constant_pool);
+        }
+    }
+
+
+    /******************** Private utility methods **********************/
+    /**
+     * Check whether the header of the file is ok.
+     * Of course, this has to be the first action on successive file reads.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readID() throws IOException, ClassFormatException {
+        int magic = 0xCAFEBABE;
+        if (file.readInt() != magic) {
+            throw new ClassFormatException(file_name + " is not a Java .class file");
+        }
+    }
+
+
+    /**
+     * Read information about the interfaces implemented by this class.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readInterfaces() throws IOException, ClassFormatException {
+        int interfaces_count;
+        interfaces_count = file.readUnsignedShort();
+        interfaces = new int[interfaces_count];
+        for (int i = 0; i < interfaces_count; i++) {
+            interfaces[i] = file.readUnsignedShort();
+        }
+    }
+
+
+    /**
+     * Read information about the methods of the class.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readMethods() throws IOException, ClassFormatException {
+        int methods_count;
+        methods_count = file.readUnsignedShort();
+        methods = new Method[methods_count];
+        for (int i = 0; i < methods_count; i++) {
+            methods[i] = new Method(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * Read major and minor version of compiler which created the file.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void readVersion() throws IOException, ClassFormatException {
+        minor = file.readUnsignedShort();
+        major = file.readUnsignedShort();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Code.java b/java/org/apache/tomcat/util/bcel/classfile/Code.java
new file mode 100644 (file)
index 0000000..af6f182
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents a chunk of Java byte code contained in a
+ * method. It is instantiated by the
+ * <em>Attribute.readAttribute()</em> method. A <em>Code</em>
+ * attribute contains informations about operand stack, local
+ * variables, byte code and the exceptions handled within this
+ * method.
+ *
+ * This attribute has attributes itself, namely <em>LineNumberTable</em> which
+ * is used for debugging purposes and <em>LocalVariableTable</em> which 
+ * contains information about the local variables.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ * @see     CodeException
+ * @see     LineNumberTable
+ * @see LocalVariableTable
+ */
+public final class Code extends Attribute {
+
+    private int max_stack; // Maximum size of stack used by this method
+    private int max_locals; // Number of local variables
+    private int code_length; // Length of code in bytes
+    private byte[] code; // Actual byte code
+    private int exception_table_length;
+    private CodeException[] exception_table; // Table of handled exceptions
+    private int attributes_count; // Attributes of code: LineNumber
+    private Attribute[] attributes; // or LocalVariable
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public Code(Code c) {
+        this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c
+                .getExceptionTable(), c.getAttributes(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     */
+    Code(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        // Initialize with some default values which will be overwritten later
+        this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null,
+                (CodeException[]) null, (Attribute[]) null, constant_pool);
+        code_length = file.readInt();
+        code = new byte[code_length]; // Read byte code
+        file.readFully(code);
+        /* Read exception table that contains all regions where an exception
+         * handler is active, i.e., a try { ... } catch() block.
+         */
+        exception_table_length = file.readUnsignedShort();
+        exception_table = new CodeException[exception_table_length];
+        for (int i = 0; i < exception_table_length; i++) {
+            exception_table[i] = new CodeException(file);
+        }
+        /* Read all attributes, currently `LineNumberTable' and
+         * `LocalVariableTable'
+         */
+        attributes_count = file.readUnsignedShort();
+        attributes = new Attribute[attributes_count];
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i] = Attribute.readAttribute(file, constant_pool);
+        }
+        /* Adjust length, because of setAttributes in this(), s.b.  length
+         * is incorrect, because it didn't take the internal attributes
+         * into account yet! Very subtle bug, fixed in 3.1.1.
+         */
+        this.length = length;
+    }
+
+
+    /**
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param max_stack Maximum size of stack
+     * @param max_locals Number of local variables
+     * @param code Actual byte code
+     * @param exception_table Table of handled exceptions
+     * @param attributes Attributes of code: LineNumber or LocalVariable
+     * @param constant_pool Array of constants
+     */
+    public Code(int name_index, int length, int max_stack, int max_locals, byte[] code,
+            CodeException[] exception_table, Attribute[] attributes, ConstantPool constant_pool) {
+        super(Constants.ATTR_CODE, name_index, length, constant_pool);
+        this.max_stack = max_stack;
+        this.max_locals = max_locals;
+        setCode(code);
+        setExceptionTable(exception_table);
+        setAttributes(attributes); // Overwrites length!
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitCode(this);
+    }
+
+
+    /**
+     * Dump code attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(max_stack);
+        file.writeShort(max_locals);
+        file.writeInt(code_length);
+        file.write(code, 0, code_length);
+        file.writeShort(exception_table_length);
+        for (int i = 0; i < exception_table_length; i++) {
+            exception_table[i].dump(file);
+        }
+        file.writeShort(attributes_count);
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Collection of code attributes.
+     * @see Attribute
+     */
+    public final Attribute[] getAttributes() {
+        return attributes;
+    }
+
+
+    /**
+     * @return LineNumberTable of Code, if it has one
+     */
+    public LineNumberTable getLineNumberTable() {
+        for (int i = 0; i < attributes_count; i++) {
+            if (attributes[i] instanceof LineNumberTable) {
+                return (LineNumberTable) attributes[i];
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @return LocalVariableTable of Code, if it has one
+     */
+    public LocalVariableTable getLocalVariableTable() {
+        for (int i = 0; i < attributes_count; i++) {
+            if (attributes[i] instanceof LocalVariableTable) {
+                return (LocalVariableTable) attributes[i];
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @return Actual byte code of the method.
+     */
+    public final byte[] getCode() {
+        return code;
+    }
+
+
+    /**
+     * @return Table of handled exceptions.
+     * @see CodeException
+     */
+    public final CodeException[] getExceptionTable() {
+        return exception_table;
+    }
+
+
+    /**
+     * @return Number of local variables.
+     */
+    public final int getMaxLocals() {
+        return max_locals;
+    }
+
+
+    /**
+     * @return Maximum size of stack used by this method.
+     */
+    public final int getMaxStack() {
+        return max_stack;
+    }
+
+
+    /**
+     * @return the internal length of this code attribute (minus the first 6 bytes) 
+     * and excluding all its attributes
+     */
+    private final int getInternalLength() {
+        return 2 /*max_stack*/+ 2 /*max_locals*/+ 4 /*code length*/
+                + code_length /*byte-code*/
+                + 2 /*exception-table length*/
+                + 8 * exception_table_length /* exception table */
+                + 2 /* attributes count */;
+    }
+
+
+    /**
+     * @return the full size of this code attribute, minus its first 6 bytes,
+     * including the size of all its contained attributes
+     */
+    private final int calculateLength() {
+        int len = 0;
+        for (int i = 0; i < attributes_count; i++) {
+            len += attributes[i].length + 6 /*attribute header size*/;
+        }
+        return len + getInternalLength();
+    }
+
+
+    /**
+     * @param attributes the attributes to set for this Code
+     */
+    public final void setAttributes( Attribute[] attributes ) {
+        this.attributes = attributes;
+        attributes_count = (attributes == null) ? 0 : attributes.length;
+        length = calculateLength(); // Adjust length
+    }
+
+
+    /**
+     * @param code byte code
+     */
+    public final void setCode( byte[] code ) {
+        this.code = code;
+        code_length = (code == null) ? 0 : code.length;
+    }
+
+
+    /**
+     * @param exception_table exception table
+     */
+    public final void setExceptionTable( CodeException[] exception_table ) {
+        this.exception_table = exception_table;
+        exception_table_length = (exception_table == null) ? 0 : exception_table.length;
+    }
+
+
+    /**
+     * @param max_locals maximum number of local variables
+     */
+    public final void setMaxLocals( int max_locals ) {
+        this.max_locals = max_locals;
+    }
+
+
+    /**
+     * @param max_stack maximum stack size
+     */
+    public final void setMaxStack( int max_stack ) {
+        this.max_stack = max_stack;
+    }
+
+
+    /**
+     * @return String representation of code chunk.
+     */
+    public final String toString( boolean verbose ) {
+        StringBuffer buf;
+        buf = new StringBuffer(100);
+        buf.append("Code(max_stack = ").append(max_stack).append(", max_locals = ").append(
+                max_locals).append(", code_length = ").append(code_length).append(")\n").append(
+                Utility.codeToString(code, constant_pool, 0, -1, verbose));
+        if (exception_table_length > 0) {
+            buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n");
+            for (int i = 0; i < exception_table_length; i++) {
+                buf.append(exception_table[i].toString(constant_pool, verbose)).append("\n");
+            }
+        }
+        if (attributes_count > 0) {
+            buf.append("\nAttribute(s) = \n");
+            for (int i = 0; i < attributes_count; i++) {
+                buf.append(attributes[i].toString()).append("\n");
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return String representation of code chunk.
+     */
+    public final String toString() {
+        return toString(true);
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     * 
+     * @param _constant_pool the constant pool to duplicate
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        Code c = (Code) clone();
+        if (code != null) {
+            c.code = new byte[code.length];
+            System.arraycopy(code, 0, c.code, 0, code.length);
+        }
+        c.constant_pool = _constant_pool;
+        c.exception_table = new CodeException[exception_table_length];
+        for (int i = 0; i < exception_table_length; i++) {
+            c.exception_table[i] = exception_table[i].copy();
+        }
+        c.attributes = new Attribute[attributes_count];
+        for (int i = 0; i < attributes_count; i++) {
+            c.attributes[i] = attributes[i].copy(_constant_pool);
+        }
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/CodeException.java b/java/org/apache/tomcat/util/bcel/classfile/CodeException.java
new file mode 100644 (file)
index 0000000..816f9f6
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents an entry in the exception table of the <em>Code</em>
+ * attribute and is used only there. It contains a range in which a
+ * particular exception handler is active.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ */
+public final class CodeException implements Cloneable, Constants, Node, Serializable {
+
+    private int start_pc; // Range in the code the exception handler is
+    private int end_pc; // active. start_pc is inclusive, end_pc exclusive
+    private int handler_pc; /* Starting address of exception handler, i.e.,
+     * an offset from start of code.
+     */
+    private int catch_type; /* If this is zero the handler catches any
+     * exception, otherwise it points to the
+     * exception class which is to be caught.
+     */
+
+
+    /**
+     * Initialize from another object.
+     */
+    public CodeException(CodeException c) {
+        this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    CodeException(DataInput file) throws IOException {
+        this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
+                .readUnsignedShort());
+    }
+
+
+    /**
+     * @param start_pc Range in the code the exception handler is active,
+     * start_pc is inclusive while
+     * @param end_pc is exclusive
+     * @param handler_pc Starting address of exception handler, i.e.,
+     * an offset from start of code.
+     * @param catch_type If zero the handler catches any 
+     * exception, otherwise it points to the exception class which is 
+     * to be caught.
+     */
+    public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) {
+        this.start_pc = start_pc;
+        this.end_pc = end_pc;
+        this.handler_pc = handler_pc;
+        this.catch_type = catch_type;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitCodeException(this);
+    }
+
+
+    /**
+     * Dump code exception to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(start_pc);
+        file.writeShort(end_pc);
+        file.writeShort(handler_pc);
+        file.writeShort(catch_type);
+    }
+
+
+    /**
+     * @return 0, if the handler catches any exception, otherwise it points to
+     * the exception class which is to be caught.
+     */
+    public final int getCatchType() {
+        return catch_type;
+    }
+
+
+    /**
+     * @return Exclusive end index of the region where the handler is active.
+     */
+    public final int getEndPC() {
+        return end_pc;
+    }
+
+
+    /**
+     * @return Starting address of exception handler, relative to the code.
+     */
+    public final int getHandlerPC() {
+        return handler_pc;
+    }
+
+
+    /**
+     * @return Inclusive start index of the region where the handler is active.
+     */
+    public final int getStartPC() {
+        return start_pc;
+    }
+
+
+    /**
+     * @param catch_type the type of exception that is caught
+     */
+    public final void setCatchType( int catch_type ) {
+        this.catch_type = catch_type;
+    }
+
+
+    /**
+     * @param end_pc end of handled block
+     */
+    public final void setEndPC( int end_pc ) {
+        this.end_pc = end_pc;
+    }
+
+
+    /**
+     * @param handler_pc where the actual code is
+     */
+    public final void setHandlerPC( int handler_pc ) {
+        this.handler_pc = handler_pc;
+    }
+
+
+    /**
+     * @param start_pc start of handled block
+     */
+    public final void setStartPC( int start_pc ) {
+        this.start_pc = start_pc;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = "
+                + handler_pc + ", catch_type = " + catch_type + ")";
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString( ConstantPool cp, boolean verbose ) {
+        String str;
+        if (catch_type == 0) {
+            str = "<Any exception>(0)";
+        } else {
+            str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false)
+                    + (verbose ? "(" + catch_type + ")" : "");
+        }
+        return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
+    }
+
+
+    public final String toString( ConstantPool cp ) {
+        return toString(cp, true);
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public CodeException copy() {
+        try {
+            return (CodeException) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Constant.java b/java/org/apache/tomcat/util/bcel/classfile/Constant.java
new file mode 100644 (file)
index 0000000..8cbedaa
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/**
+ * Abstract superclass for classes to represent the different constant types
+ * in the constant pool of a class file. The classes keep closely to
+ * the JVM specification.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class Constant implements Cloneable, Node, Serializable {
+
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            Constant THIS = (Constant) o1;
+            Constant THAT = (Constant) o2;
+            return THIS.toString().equals(THAT.toString());
+        }
+
+
+        public int hashCode( Object o ) {
+            Constant THIS = (Constant) o;
+            return THIS.toString().hashCode();
+        }
+    };
+    /* In fact this tag is redundant since we can distinguish different
+     * `Constant' objects by their type, i.e., via `instanceof'. In some
+     * places we will use the tag for switch()es anyway.
+     *
+     * First, we want match the specification as closely as possible. Second we
+     * need the tag as an index to select the corresponding class name from the 
+     * `CONSTANT_NAMES' array.
+     */
+    protected byte tag;
+
+
+    Constant(byte tag) {
+        this.tag = tag;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public abstract void accept( Visitor v );
+
+
+    public abstract void dump( DataOutputStream file ) throws IOException;
+
+
+    /**
+     * @return Tag of constant, i.e., its type. No setTag() method to avoid
+     * confusion.
+     */
+    public final byte getTag() {
+        return tag;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public String toString() {
+        return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
+    }
+
+
+    /**
+     * @return deep copy of this constant
+     */
+    public Constant copy() {
+        try {
+            return (Constant) super.clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+
+
+    public Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
+
+    /**
+     * Read one constant from the given file, the type depends on a tag byte.
+     *
+     * @param file Input stream
+     * @return Constant object
+     */
+    static final Constant readConstant( DataInputStream file ) throws IOException,
+            ClassFormatException {
+        byte b = file.readByte(); // Read tag byte
+        switch (b) {
+            case Constants.CONSTANT_Class:
+                return new ConstantClass(file);
+            case Constants.CONSTANT_Fieldref:
+                return new ConstantFieldref(file);
+            case Constants.CONSTANT_Methodref:
+                return new ConstantMethodref(file);
+            case Constants.CONSTANT_InterfaceMethodref:
+                return new ConstantInterfaceMethodref(file);
+            case Constants.CONSTANT_String:
+                return new ConstantString(file);
+            case Constants.CONSTANT_Integer:
+                return new ConstantInteger(file);
+            case Constants.CONSTANT_Float:
+                return new ConstantFloat(file);
+            case Constants.CONSTANT_Long:
+                return new ConstantLong(file);
+            case Constants.CONSTANT_Double:
+                return new ConstantDouble(file);
+            case Constants.CONSTANT_NameAndType:
+                return new ConstantNameAndType(file);
+            case Constants.CONSTANT_Utf8:
+                return new ConstantUtf8(file);
+            default:
+                throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
+        }
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two Constant objects are said to be equal when
+     * the result of toString() is equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the result of toString().
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantCP.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantCP.java
new file mode 100644 (file)
index 0000000..907ed71
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Abstract super class for Fieldref and Methodref constants.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     ConstantFieldref
+ * @see     ConstantMethodref
+ * @see     ConstantInterfaceMethodref
+ */
+public abstract class ConstantCP extends Constant {
+
+    /** References to the constants containing the class and the field signature
+     */
+    protected int class_index, name_and_type_index;
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantCP(ConstantCP c) {
+        this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param tag  Constant type tag
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantCP(byte tag, DataInput file) throws IOException {
+        this(tag, file.readUnsignedShort(), file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param class_index Reference to the class containing the field
+     * @param name_and_type_index and the field signature
+     */
+    protected ConstantCP(byte tag, int class_index, int name_and_type_index) {
+        super(tag);
+        this.class_index = class_index;
+        this.name_and_type_index = name_and_type_index;
+    }
+
+
+    /** 
+     * Dump constant field reference to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeShort(class_index);
+        file.writeShort(name_and_type_index);
+    }
+
+
+    /**
+     * @return Reference (index) to class this field or method belongs to.
+     */
+    public final int getClassIndex() {
+        return class_index;
+    }
+
+
+    /**
+     * @return Reference (index) to signature of the field.
+     */
+    public final int getNameAndTypeIndex() {
+        return name_and_type_index;
+    }
+
+
+    /**
+     * @param class_index points to Constant_class 
+     */
+    public final void setClassIndex( int class_index ) {
+        this.class_index = class_index;
+    }
+
+
+    /**
+     * @return Class this field belongs to.
+     */
+    public String getClass( ConstantPool cp ) {
+        return cp.constantToString(class_index, Constants.CONSTANT_Class);
+    }
+
+
+    /**
+     * @param name_and_type_index points to Constant_NameAndType
+     */
+    public final void setNameAndTypeIndex( int name_and_type_index ) {
+        this.name_and_type_index = name_and_type_index;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(class_index = " + class_index + ", name_and_type_index = "
+                + name_and_type_index + ")";
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantClass.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantClass.java
new file mode 100644 (file)
index 0000000..45bd8a6
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a (external) class.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantClass extends Constant implements ConstantObject {
+
+    private int name_index; // Identical to ConstantString except for the name
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantClass(ConstantClass c) {
+        this(c.getNameIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantClass(DataInput file) throws IOException {
+        this(file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param name_index Name index in constant pool.  Should refer to a
+     * ConstantUtf8.
+     */
+    public ConstantClass(int name_index) {
+        super(Constants.CONSTANT_Class);
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantClass(this);
+    }
+
+
+    /** 
+     * Dump constant class to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeShort(name_index);
+    }
+
+
+    /**
+     * @return Name index in constant pool of class name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /**
+     * @param name_index the name index in the constant pool of this Constant Class
+     */
+    public final void setNameIndex( int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /** @return String object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8);
+        return ((ConstantUtf8) c).getBytes();
+    }
+
+
+    /** @return dereferenced string
+     */
+    public String getBytes( ConstantPool cp ) {
+        return (String) getConstantValue(cp);
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(name_index = " + name_index + ")";
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantDouble.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantDouble.java
new file mode 100644 (file)
index 0000000..d0b0e9c
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a Double object.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantDouble extends Constant implements ConstantObject {
+
+    private double bytes;
+
+
+    /** 
+     * @param bytes Data
+     */
+    public ConstantDouble(double bytes) {
+        super(Constants.CONSTANT_Double);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantDouble(ConstantDouble c) {
+        this(c.getBytes());
+    }
+
+
+    /** 
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantDouble(DataInput file) throws IOException {
+        this(file.readDouble());
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantDouble(this);
+    }
+
+
+    /**
+     * Dump constant double to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeDouble(bytes);
+    }
+
+
+    /**
+     * @return data, i.e., 8 bytes.
+     */
+    public final double getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes the raw bytes that represent the double value
+     */
+    public final void setBytes( double bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(bytes = " + bytes + ")";
+    }
+
+
+    /** @return Double object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        return new Double(bytes);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantFieldref.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantFieldref.java
new file mode 100644 (file)
index 0000000..b294ced
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents a constant pool reference to a field.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class ConstantFieldref extends ConstantCP {
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantFieldref(ConstantFieldref c) {
+        super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file input stream
+     * @throws IOException
+     */
+    ConstantFieldref(DataInputStream file) throws IOException {
+        super(Constants.CONSTANT_Fieldref, file);
+    }
+
+
+    /**
+     * @param class_index Reference to the class containing the Field
+     * @param name_and_type_index and the Field signature
+     */
+    public ConstantFieldref(int class_index, int name_and_type_index) {
+        super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of Fields,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantFieldref(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantFloat.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantFloat.java
new file mode 100644 (file)
index 0000000..8551914
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a float object.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantFloat extends Constant implements ConstantObject {
+
+    private float bytes;
+
+
+    /** 
+     * @param bytes Data
+     */
+    public ConstantFloat(float bytes) {
+        super(Constants.CONSTANT_Float);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public ConstantFloat(ConstantFloat c) {
+        this(c.getBytes());
+    }
+
+
+    /** 
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantFloat(DataInput file) throws IOException {
+        this(file.readFloat());
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantFloat(this);
+    }
+
+
+    /**
+     * Dump constant float to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeFloat(bytes);
+    }
+
+
+    /**
+     * @return data, i.e., 4 bytes.
+     */
+    public final float getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes the raw bytes that represent this float
+     */
+    public final void setBytes( float bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(bytes = " + bytes + ")";
+    }
+
+
+    /** @return Float object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        return new Float(bytes);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantInteger.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantInteger.java
new file mode 100644 (file)
index 0000000..d862c04
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to an int object.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantInteger extends Constant implements ConstantObject {
+
+    private int bytes;
+
+
+    /** 
+     * @param bytes Data
+     */
+    public ConstantInteger(int bytes) {
+        super(Constants.CONSTANT_Integer);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantInteger(ConstantInteger c) {
+        this(c.getBytes());
+    }
+
+
+    /** 
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantInteger(DataInput file) throws IOException {
+        this(file.readInt());
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantInteger(this);
+    }
+
+
+    /**
+     * Dump constant integer to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeInt(bytes);
+    }
+
+
+    /**
+     * @return data, i.e., 4 bytes.
+     */
+    public final int getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes the raw bytes that represent this integer
+     */
+    public final void setBytes( int bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(bytes = " + bytes + ")";
+    }
+
+
+    /** @return Integer object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        return new Integer(bytes);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantInterfaceMethodref.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantInterfaceMethodref.java
new file mode 100644 (file)
index 0000000..41da17b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents a constant pool reference to an interface method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class ConstantInterfaceMethodref extends ConstantCP {
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) {
+        super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file input stream
+     * @throws IOException
+     */
+    ConstantInterfaceMethodref(DataInputStream file) throws IOException {
+        super(Constants.CONSTANT_InterfaceMethodref, file);
+    }
+
+
+    /**
+     * @param class_index Reference to the class containing the method
+     * @param name_and_type_index and the method signature
+     */
+    public ConstantInterfaceMethodref(int class_index, int name_and_type_index) {
+        super(Constants.CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantInterfaceMethodref(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantLong.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantLong.java
new file mode 100644 (file)
index 0000000..d8837e8
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a long object.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantLong extends Constant implements ConstantObject {
+
+    private long bytes;
+
+
+    /** 
+     * @param bytes Data
+     */
+    public ConstantLong(long bytes) {
+        super(Constants.CONSTANT_Long);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantLong(ConstantLong c) {
+        this(c.getBytes());
+    }
+
+
+    /** 
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantLong(DataInput file) throws IOException {
+        this(file.readLong());
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantLong(this);
+    }
+
+
+    /**
+     * Dump constant long to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeLong(bytes);
+    }
+
+
+    /**
+     * @return data, i.e., 8 bytes.
+     */
+    public final long getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes thr raw bytes that represent this long
+     */
+    public final void setBytes( long bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(bytes = " + bytes + ")";
+    }
+
+
+    /** @return Long object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        return new Long(bytes);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantMethodref.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantMethodref.java
new file mode 100644 (file)
index 0000000..c40f0aa
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents a constant pool reference to a method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class ConstantMethodref extends ConstantCP {
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantMethodref(ConstantMethodref c) {
+        super(Constants.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file input stream
+     * @throws IOException
+     */
+    ConstantMethodref(DataInputStream file) throws IOException {
+        super(Constants.CONSTANT_Methodref, file);
+    }
+
+
+    /**
+     * @param class_index Reference to the class containing the method
+     * @param name_and_type_index and the method signature
+     */
+    public ConstantMethodref(int class_index, int name_and_type_index) {
+        super(Constants.CONSTANT_Methodref, class_index, name_and_type_index);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantMethodref(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantNameAndType.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantNameAndType.java
new file mode 100644 (file)
index 0000000..00e46c2
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to the name and signature
+ * of a field or method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantNameAndType extends Constant {
+
+    private int name_index; // Name of field/method
+    private int signature_index; // and its signature.
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantNameAndType(ConstantNameAndType c) {
+        this(c.getNameIndex(), c.getSignatureIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantNameAndType(DataInput file) throws IOException {
+        this(file.readUnsignedShort(), file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param name_index Name of field/method
+     * @param signature_index and its signature
+     */
+    public ConstantNameAndType(int name_index, int signature_index) {
+        super(Constants.CONSTANT_NameAndType);
+        this.name_index = name_index;
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantNameAndType(this);
+    }
+
+
+    /**
+     * Dump name and signature index to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeShort(name_index);
+        file.writeShort(signature_index);
+    }
+
+
+    /**
+     * @return Name index in constant pool of field/method name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /** @return name
+     */
+    public final String getName( ConstantPool cp ) {
+        return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8);
+    }
+
+
+    /**
+     * @return Index in constant pool of field/method signature.
+     */
+    public final int getSignatureIndex() {
+        return signature_index;
+    }
+
+
+    /** @return signature
+     */
+    public final String getSignature( ConstantPool cp ) {
+        return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8);
+    }
+
+
+    /**
+     * @param name_index the name index of this constant
+     */
+    public final void setNameIndex( int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * @param signature_index the signature index in the constant pool of this type
+     */
+    public final void setSignatureIndex( int signature_index ) {
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return super.toString() + "(name_index = " + name_index + ", signature_index = "
+                + signature_index + ")";
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantObject.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantObject.java
new file mode 100644 (file)
index 0000000..3d34394
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/** 
+ * This interface denotes those constants that have a "natural" value,
+ * such as ConstantLong, ConstantString, etc..
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public interface ConstantObject {
+
+    /** @return object representing the constant, e.g., Long for ConstantLong
+     */
+    public abstract Object getConstantValue( ConstantPool cp );
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantPool.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantPool.java
new file mode 100644 (file)
index 0000000..612d345
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents the constant pool, i.e., a table of constants, of
+ * a parsed classfile. It may contain null references, due to the JVM
+ * specification that skips an entry after an 8-byte constant (double,
+ * long) entry.  Those interested in generating constant pools
+ * programatically should see <a href="../generic/ConstantPoolGen.html">
+ * ConstantPoolGen</a>.
+
+ * @version $Id$
+ * @see     Constant
+ * @see     org.apache.tomcat.util.bcel.generic.ConstantPoolGen
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ConstantPool implements Cloneable, Node, Serializable {
+
+    private int constant_pool_count;
+    private Constant[] constant_pool;
+
+
+    /**
+     * @param constant_pool Array of constants
+     */
+    public ConstantPool(Constant[] constant_pool) {
+        setConstantPool(constant_pool);
+    }
+
+
+    /**
+     * Read constants from given file stream.
+     *
+     * @param file Input stream
+     * @throws IOException
+     * @throws ClassFormatException
+     */
+    ConstantPool(DataInputStream file) throws IOException, ClassFormatException {
+        byte tag;
+        constant_pool_count = file.readUnsignedShort();
+        constant_pool = new Constant[constant_pool_count];
+        /* constant_pool[0] is unused by the compiler and may be used freely
+         * by the implementation.
+         */
+        for (int i = 1; i < constant_pool_count; i++) {
+            constant_pool[i] = Constant.readConstant(file);
+            /* Quote from the JVM specification:
+             * "All eight byte constants take up two spots in the constant pool.
+             * If this is the n'th byte in the constant pool, then the next item
+             * will be numbered n+2"
+             * 
+             * Thus we have to increment the index counter.
+             */
+            tag = constant_pool[i].getTag();
+            if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) {
+                i++;
+            }
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantPool(this);
+    }
+
+
+    /**
+     * Resolve constant to a string representation.
+     *
+     * @param  c Constant to be printed
+     * @return String representation
+     */
+    public String constantToString( Constant c ) throws ClassFormatException {
+        String str;
+        int i;
+        byte tag = c.getTag();
+        switch (tag) {
+            case Constants.CONSTANT_Class:
+                i = ((ConstantClass) c).getNameIndex();
+                c = getConstant(i, Constants.CONSTANT_Utf8);
+                str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false);
+                break;
+            case Constants.CONSTANT_String:
+                i = ((ConstantString) c).getStringIndex();
+                c = getConstant(i, Constants.CONSTANT_Utf8);
+                str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\"";
+                break;
+            case Constants.CONSTANT_Utf8:
+                str = ((ConstantUtf8) c).getBytes();
+                break;
+            case Constants.CONSTANT_Double:
+                str = String.valueOf(((ConstantDouble) c).getBytes());
+                break;
+            case Constants.CONSTANT_Float:
+                str = String.valueOf(((ConstantFloat) c).getBytes());
+                break;
+            case Constants.CONSTANT_Long:
+                str = String.valueOf(((ConstantLong) c).getBytes());
+                break;
+            case Constants.CONSTANT_Integer:
+                str = String.valueOf(((ConstantInteger) c).getBytes());
+                break;
+            case Constants.CONSTANT_NameAndType:
+                str = (constantToString(((ConstantNameAndType) c).getNameIndex(),
+                        Constants.CONSTANT_Utf8)
+                        + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(),
+                        Constants.CONSTANT_Utf8));
+                break;
+            case Constants.CONSTANT_InterfaceMethodref:
+            case Constants.CONSTANT_Methodref:
+            case Constants.CONSTANT_Fieldref:
+                str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class)
+                        + "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(),
+                        Constants.CONSTANT_NameAndType));
+                break;
+            default: // Never reached
+                throw new RuntimeException("Unknown constant type " + tag);
+        }
+        return str;
+    }
+
+
+    private static final String escape( String str ) {
+        int len = str.length();
+        StringBuffer buf = new StringBuffer(len + 5);
+        char[] ch = str.toCharArray();
+        for (int i = 0; i < len; i++) {
+            switch (ch[i]) {
+                case '\n':
+                    buf.append("\\n");
+                    break;
+                case '\r':
+                    buf.append("\\r");
+                    break;
+                case '\t':
+                    buf.append("\\t");
+                    break;
+                case '\b':
+                    buf.append("\\b");
+                    break;
+                case '"':
+                    buf.append("\\\"");
+                    break;
+                default:
+                    buf.append(ch[i]);
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * Retrieve constant at `index' from constant pool and resolve it to
+     * a string representation.
+     *
+     * @param  index of constant in constant pool
+     * @param  tag expected type
+     * @return String representation
+     */
+    public String constantToString( int index, byte tag ) throws ClassFormatException {
+        Constant c = getConstant(index, tag);
+        return constantToString(c);
+    }
+
+
+    /** 
+     * Dump constant pool to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(constant_pool_count);
+        for (int i = 1; i < constant_pool_count; i++) {
+            if (constant_pool[i] != null) {
+                constant_pool[i].dump(file);
+            }
+        }
+    }
+
+
+    /**
+     * Get constant from constant pool.
+     *
+     * @param  index Index in constant pool
+     * @return Constant value
+     * @see    Constant
+     */
+    public Constant getConstant( int index ) {
+        if (index >= constant_pool.length || index < 0) {
+            throw new ClassFormatException("Invalid constant pool reference: " + index
+                    + ". Constant pool size is: " + constant_pool.length);
+        }
+        return constant_pool[index];
+    }
+
+
+    /**
+     * Get constant from constant pool and check whether it has the
+     * expected type.
+     *
+     * @param  index Index in constant pool
+     * @param  tag Tag of expected constant, i.e., its type
+     * @return Constant value
+     * @see    Constant
+     * @throws  ClassFormatException
+     */
+    public Constant getConstant( int index, byte tag ) throws ClassFormatException {
+        Constant c;
+        c = getConstant(index);
+        if (c == null) {
+            throw new ClassFormatException("Constant pool at index " + index + " is null.");
+        }
+        if (c.getTag() != tag) {
+            throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag]
+                    + "' at index " + index + " and got " + c);
+        }
+        return c;
+    }
+
+
+    /**
+     * @return Array of constants.
+     * @see    Constant
+     */
+    public Constant[] getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * Get string from constant pool and bypass the indirection of 
+     * `ConstantClass' and `ConstantString' objects. I.e. these classes have
+     * an index field that points to another entry of the constant pool of
+     * type `ConstantUtf8' which contains the real data.
+     *
+     * @param  index Index in constant pool
+     * @param  tag Tag of expected constant, either ConstantClass or ConstantString
+     * @return Contents of string reference
+     * @see    ConstantClass
+     * @see    ConstantString
+     * @throws  ClassFormatException
+     */
+    public String getConstantString( int index, byte tag ) throws ClassFormatException {
+        Constant c;
+        int i;
+        c = getConstant(index, tag);
+        /* This switch() is not that elegant, since the two classes have the
+         * same contents, they just differ in the name of the index
+         * field variable.
+         * But we want to stick to the JVM naming conventions closely though
+         * we could have solved these more elegantly by using the same
+         * variable name or by subclassing.
+         */
+        switch (tag) {
+            case Constants.CONSTANT_Class:
+                i = ((ConstantClass) c).getNameIndex();
+                break;
+            case Constants.CONSTANT_String:
+                i = ((ConstantString) c).getStringIndex();
+                break;
+            default:
+                throw new RuntimeException("getConstantString called with illegal tag " + tag);
+        }
+        // Finally get the string from the constant pool
+        c = getConstant(i, Constants.CONSTANT_Utf8);
+        return ((ConstantUtf8) c).getBytes();
+    }
+
+
+    /**
+     * @return Length of constant pool.
+     */
+    public int getLength() {
+        return constant_pool_count;
+    }
+
+
+    /**
+     * @param constant Constant to set
+     */
+    public void setConstant( int index, Constant constant ) {
+        constant_pool[index] = constant;
+    }
+
+
+    /**
+     * @param constant_pool
+     */
+    public void setConstantPool( Constant[] constant_pool ) {
+        this.constant_pool = constant_pool;
+        constant_pool_count = (constant_pool == null) ? 0 : constant_pool.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 1; i < constant_pool_count; i++) {
+            buf.append(i).append(")").append(constant_pool[i]).append("\n");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this constant pool
+     */
+    public ConstantPool copy() {
+        ConstantPool c = null;
+        try {
+            c = (ConstantPool) clone();
+            c.constant_pool = new Constant[constant_pool_count];
+            for (int i = 1; i < constant_pool_count; i++) {
+                if (constant_pool[i] != null) {
+                    c.constant_pool[i] = constant_pool[i].copy();
+                }
+            }
+        } catch (CloneNotSupportedException e) {
+        }
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantString.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantString.java
new file mode 100644 (file)
index 0000000..d063a10
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a String object.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantString extends Constant implements ConstantObject {
+
+    private int string_index; // Identical to ConstantClass except for this name
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantString(ConstantString c) {
+        this(c.getStringIndex());
+    }
+
+
+    /** 
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantString(DataInput file) throws IOException {
+        this(file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param string_index Index of Constant_Utf8 in constant pool
+     */
+    public ConstantString(int string_index) {
+        super(Constants.CONSTANT_String);
+        this.string_index = string_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantString(this);
+    }
+
+
+    /**
+     * Dump constant field reference to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeShort(string_index);
+    }
+
+
+    /**
+     * @return Index in constant pool of the string (ConstantUtf8).
+     */
+    public final int getStringIndex() {
+        return string_index;
+    }
+
+
+    /**
+     * @param string_index the index into the constant of the string value
+     */
+    public final void setStringIndex( int string_index ) {
+        this.string_index = string_index;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return super.toString() + "(string_index = " + string_index + ")";
+    }
+
+
+    /** @return String object
+     */
+    public Object getConstantValue( ConstantPool cp ) {
+        Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8);
+        return ((ConstantUtf8) c).getBytes();
+    }
+
+
+    /** @return dereferenced string
+     */
+    public String getBytes( ConstantPool cp ) {
+        return (String) getConstantValue(cp);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantUtf8.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantUtf8.java
new file mode 100644 (file)
index 0000000..ea7b105
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class is derived from the abstract 
+ * <A HREF="org.apache.tomcat.util.bcel.classfile.Constant.html">Constant</A> class 
+ * and represents a reference to a Utf8 encoded string.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Constant
+ */
+public final class ConstantUtf8 extends Constant {
+
+    private String bytes;
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantUtf8(ConstantUtf8 c) {
+        this(c.getBytes());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantUtf8(DataInput file) throws IOException {
+        super(Constants.CONSTANT_Utf8);
+        bytes = file.readUTF();
+    }
+
+
+    /**
+     * @param bytes Data
+     */
+    public ConstantUtf8(String bytes) {
+        super(Constants.CONSTANT_Utf8);
+        if (bytes == null) {
+            throw new IllegalArgumentException("bytes must not be null!");
+        }
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantUtf8(this);
+    }
+
+
+    /**
+     * Dump String in Utf8 format to file stream.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(tag);
+        file.writeUTF(bytes);
+    }
+
+
+    /**
+     * @return Data converted to string.
+     */
+    public final String getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes the raw bytes of this Utf-8
+     */
+    public final void setBytes( String bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")";
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ConstantValue.java b/java/org/apache/tomcat/util/bcel/classfile/ConstantValue.java
new file mode 100644 (file)
index 0000000..7b488b0
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a constant 
+ * value, i.e., a default value for initializing a class field.
+ * This class is instantiated by the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class ConstantValue extends Attribute {
+
+    private int constantvalue_index;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public ConstantValue(ConstantValue c) {
+        this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Name index in constant pool
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    ConstantValue(int name_index, int length, DataInput file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, file.readUnsignedShort(), constant_pool);
+    }
+
+
+    /**
+     * @param name_index Name index in constant pool
+     * @param length Content length in bytes
+     * @param constantvalue_index Index in constant pool
+     * @param constant_pool Array of constants
+     */
+    public ConstantValue(int name_index, int length, int constantvalue_index,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool);
+        this.constantvalue_index = constantvalue_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitConstantValue(this);
+    }
+
+
+    /**
+     * Dump constant value attribute to file stream on binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(constantvalue_index);
+    }
+
+
+    /**
+     * @return Index in constant pool of constant value.
+     */
+    public final int getConstantValueIndex() {
+        return constantvalue_index;
+    }
+
+
+    /**
+     * @param constantvalue_index the index info the constant pool of this constant value
+     */
+    public final void setConstantValueIndex( int constantvalue_index ) {
+        this.constantvalue_index = constantvalue_index;
+    }
+
+
+    /**
+     * @return String representation of constant value.
+     */
+    public final String toString() {
+        Constant c = constant_pool.getConstant(constantvalue_index);
+        String buf;
+        int i;
+        // Print constant to string depending on its type
+        switch (c.getTag()) {
+            case Constants.CONSTANT_Long:
+                buf = String.valueOf(((ConstantLong) c).getBytes());
+                break;
+            case Constants.CONSTANT_Float:
+                buf = String.valueOf(((ConstantFloat) c).getBytes());
+                break;
+            case Constants.CONSTANT_Double:
+                buf = String.valueOf(((ConstantDouble) c).getBytes());
+                break;
+            case Constants.CONSTANT_Integer:
+                buf = String.valueOf(((ConstantInteger) c).getBytes());
+                break;
+            case Constants.CONSTANT_String:
+                i = ((ConstantString) c).getStringIndex();
+                c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8);
+                buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\"";
+                break;
+            default:
+                throw new IllegalStateException("Type of ConstValue invalid: " + c);
+        }
+        return buf;
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        ConstantValue c = (ConstantValue) clone();
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Deprecated.java b/java/org/apache/tomcat/util/bcel/classfile/Deprecated.java
new file mode 100644 (file)
index 0000000..47833ae
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and denotes that this is a
+ * deprecated method.
+ * It is instantiated from the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class Deprecated extends Attribute {
+
+    private byte[] bytes;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public Deprecated(Deprecated c) {
+        this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param bytes Attribute contents
+     * @param constant_pool Array of constants
+     */
+    public Deprecated(int name_index, int length, byte[] bytes, ConstantPool constant_pool) {
+        super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    Deprecated(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (byte[]) null, constant_pool);
+        if (length > 0) {
+            bytes = new byte[length];
+            file.readFully(bytes);
+            System.err.println("Deprecated attribute with length > 0");
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitDeprecated(this);
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        if (length > 0) {
+            file.write(bytes, 0, length);
+        }
+    }
+
+
+    /**
+     * @return data bytes.
+     */
+    public final byte[] getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes the raw bytes that represents this byte array
+     */
+    public final void setBytes( byte[] bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return attribute name
+     */
+    public final String toString() {
+        return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED];
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        Deprecated c = (Deprecated) clone();
+        if (bytes != null) {
+            c.bytes = new byte[bytes.length];
+            System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/DescendingVisitor.java b/java/org/apache/tomcat/util/bcel/classfile/DescendingVisitor.java
new file mode 100644 (file)
index 0000000..7aafd4e
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.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$
+ * @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 visitAnnotation(Annotations annotation)
+       {
+               stack.push(annotation);
+               annotation.accept(visitor);
+               AnnotationEntry[] entries = annotation.getAnnotationEntries();
+               for (int i = 0; i < entries.length; i++)
+               {
+                       entries[i].accept(this);
+               }
+               stack.pop();
+       }
+
+       public void visitAnnotationEntry(AnnotationEntry annotationEntry)
+       {
+               stack.push(annotationEntry);
+               annotationEntry.accept(visitor);
+               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 visitStackMapTable(StackMapTable table)
+       {
+               stack.push(table);
+               table.accept(visitor);
+               StackMapTableEntry[] vars = table.getStackMapTable();
+               for (int i = 0; i < vars.length; i++)
+               {
+                       vars[i].accept(this);
+               }
+               stack.pop();
+       }
+
+       public void visitStackMapTableEntry(StackMapTableEntry 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();
+       }
+
+       public void visitAnnotationDefault(AnnotationDefault obj)
+       {
+               stack.push(obj);
+               obj.accept(visitor);
+               stack.pop();
+       }
+
+       public void visitEnclosingMethod(EnclosingMethod obj)
+       {
+               stack.push(obj);
+               obj.accept(visitor);
+               stack.pop();
+       }
+
+       public void visitLocalVariableTypeTable(LocalVariableTypeTable obj)
+       {
+               stack.push(obj);
+               obj.accept(visitor);
+               stack.pop();
+       }
+
+       public void visitParameterAnnotation(ParameterAnnotations obj)
+       {
+               stack.push(obj);
+               obj.accept(visitor);
+               stack.pop();
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/ElementValue.java
new file mode 100644 (file)
index 0000000..f16616c
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * @version $Id: ElementValue
+ * @author <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public abstract class ElementValue
+{
+       protected int type;
+
+       protected ConstantPool cpool;
+
+       public String toString()
+       {
+               return stringifyValue();
+       }
+
+       protected ElementValue(int type, ConstantPool cpool)
+       {
+               this.type = type;
+               this.cpool = cpool;
+       }
+
+       public int getElementValueType()
+       {
+               return type;
+       }
+
+       public abstract String stringifyValue();
+
+       public abstract void dump(DataOutputStream dos) throws IOException;
+
+       public static final int STRING = 's';
+
+       public static final int ENUM_CONSTANT = 'e';
+
+       public static final int CLASS = 'c';
+
+       public static final int ANNOTATION = '@';
+
+       public static final int ARRAY = '[';
+
+       public static final int PRIMITIVE_INT = 'I';
+
+       public static final int PRIMITIVE_BYTE = 'B';
+
+       public static final int PRIMITIVE_CHAR = 'C';
+
+       public static final int PRIMITIVE_DOUBLE = 'D';
+
+       public static final int PRIMITIVE_FLOAT = 'F';
+
+       public static final int PRIMITIVE_LONG = 'J';
+
+       public static final int PRIMITIVE_SHORT = 'S';
+
+       public static final int PRIMITIVE_BOOLEAN = 'Z';
+
+       public static ElementValue readElementValue(DataInputStream dis,
+                       ConstantPool cpool) throws IOException
+       {
+               byte type = dis.readByte();
+               switch (type)
+               {
+               case 'B': // byte
+                       return new SimpleElementValue(PRIMITIVE_BYTE, dis
+                                       .readUnsignedShort(), cpool);
+               case 'C': // char
+                       return new SimpleElementValue(PRIMITIVE_CHAR, dis
+                                       .readUnsignedShort(), cpool);
+               case 'D': // double
+                       return new SimpleElementValue(PRIMITIVE_DOUBLE, dis
+                                       .readUnsignedShort(), cpool);
+               case 'F': // float
+                       return new SimpleElementValue(PRIMITIVE_FLOAT, dis
+                                       .readUnsignedShort(), cpool);
+               case 'I': // int
+                       return new SimpleElementValue(PRIMITIVE_INT, dis
+                                       .readUnsignedShort(), cpool);
+               case 'J': // long
+                       return new SimpleElementValue(PRIMITIVE_LONG, dis
+                                       .readUnsignedShort(), cpool);
+               case 'S': // short
+                       return new SimpleElementValue(PRIMITIVE_SHORT, dis
+                                       .readUnsignedShort(), cpool);
+               case 'Z': // boolean
+                       return new SimpleElementValue(PRIMITIVE_BOOLEAN, dis
+                                       .readUnsignedShort(), cpool);
+               case 's': // String
+                       return new SimpleElementValue(STRING, dis.readUnsignedShort(),
+                                       cpool);
+               case 'e': // Enum constant
+                       return new EnumElementValue(ENUM_CONSTANT, dis.readUnsignedShort(),
+                                       dis.readUnsignedShort(), cpool);
+               case 'c': // Class
+                       return new ClassElementValue(CLASS, dis.readUnsignedShort(), cpool);
+               case '@': // Annotation
+                       // TODO isRuntimeVisible
+                       return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(
+                                       dis, cpool, false), cpool);
+               case '[': // Array
+                       int numArrayVals = dis.readUnsignedShort();
+                       ElementValue[] evalues = new ElementValue[numArrayVals];
+                       for (int j = 0; j < numArrayVals; j++)
+                       {
+                               evalues[j] = ElementValue.readElementValue(dis, cpool);
+                       }
+                       return new ArrayElementValue(ARRAY, evalues, cpool);
+               default:
+                       throw new RuntimeException(
+                                       "Unexpected element value kind in annotation: " + type);
+               }
+       }
+
+       public String toShortString()
+       {
+               StringBuffer result = new StringBuffer();
+               result.append(stringifyValue());
+               return result.toString();
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ElementValuePair.java b/java/org/apache/tomcat/util/bcel/classfile/ElementValuePair.java
new file mode 100644 (file)
index 0000000..4c36a64
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * an annotation's element value pair
+ * 
+ * @version $Id: ElementValuePair
+ * @author <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class ElementValuePair
+{
+       private ElementValue elementValue;
+
+       private ConstantPool constantPool;
+
+       private int elementNameIndex;
+
+       public ElementValuePair(int elementNameIndex, ElementValue elementValue,
+                       ConstantPool constantPool)
+       {
+               this.elementValue = elementValue;
+               this.elementNameIndex = elementNameIndex;
+               this.constantPool = constantPool;
+       }
+
+       public String getNameString()
+       {
+               ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant(
+                               elementNameIndex, Constants.CONSTANT_Utf8);
+               return c.getBytes();
+       }
+
+       public final ElementValue getValue()
+       {
+               return elementValue;
+       }
+
+       public int getNameIndex()
+       {
+               return elementNameIndex;
+       }
+
+       public String toShortString()
+       {
+               StringBuffer result = new StringBuffer();
+               result.append(getNameString()).append("=").append(
+                               getValue().toShortString());
+               return result.toString();
+       }
+       
+       protected void dump(DataOutputStream dos) throws IOException {
+               dos.writeShort(elementNameIndex); // u2 name of the element
+               elementValue.dump(dos);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/EmptyVisitor.java b/java/org/apache/tomcat/util/bcel/classfile/EmptyVisitor.java
new file mode 100644 (file)
index 0000000..5a1d861
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/**
+ * Visitor with empty method bodies, can be extended and used in conjunction
+ * with the DescendingVisitor class, e.g. By courtesy of David Spencer.
+ * 
+ * @see DescendingVisitor
+ * @version $Id$
+ */
+public class EmptyVisitor implements Visitor
+{
+       protected EmptyVisitor()
+       {
+       }
+
+       public void visitAnnotation(Annotations obj)
+       {
+       }
+
+       public void visitParameterAnnotation(ParameterAnnotations obj)
+       {
+       }
+
+       public void visitAnnotationEntry(AnnotationEntry obj)
+       {
+       }
+
+       public void visitAnnotationDefault(AnnotationDefault obj)
+       {
+       }
+
+       public void visitCode(Code obj)
+       {
+       }
+
+       public void visitCodeException(CodeException obj)
+       {
+       }
+
+       public void visitConstantClass(ConstantClass obj)
+       {
+       }
+
+       public void visitConstantDouble(ConstantDouble obj)
+       {
+       }
+
+       public void visitConstantFieldref(ConstantFieldref obj)
+       {
+       }
+
+       public void visitConstantFloat(ConstantFloat obj)
+       {
+       }
+
+       public void visitConstantInteger(ConstantInteger obj)
+       {
+       }
+
+       public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj)
+       {
+       }
+
+       public void visitConstantLong(ConstantLong obj)
+       {
+       }
+
+       public void visitConstantMethodref(ConstantMethodref obj)
+       {
+       }
+
+       public void visitConstantNameAndType(ConstantNameAndType obj)
+       {
+       }
+
+       public void visitConstantPool(ConstantPool obj)
+       {
+       }
+
+       public void visitConstantString(ConstantString obj)
+       {
+       }
+
+       public void visitConstantUtf8(ConstantUtf8 obj)
+       {
+       }
+
+       public void visitConstantValue(ConstantValue obj)
+       {
+       }
+
+       public void visitDeprecated(Deprecated obj)
+       {
+       }
+
+       public void visitExceptionTable(ExceptionTable obj)
+       {
+       }
+
+       public void visitField(Field obj)
+       {
+       }
+
+       public void visitInnerClass(InnerClass obj)
+       {
+       }
+
+       public void visitInnerClasses(InnerClasses obj)
+       {
+       }
+
+       public void visitJavaClass(JavaClass obj)
+       {
+       }
+
+       public void visitLineNumber(LineNumber obj)
+       {
+       }
+
+       public void visitLineNumberTable(LineNumberTable obj)
+       {
+       }
+
+       public void visitLocalVariable(LocalVariable obj)
+       {
+       }
+
+       public void visitLocalVariableTable(LocalVariableTable obj)
+       {
+       }
+
+       public void visitMethod(Method obj)
+       {
+       }
+
+       public void visitSignature(Signature obj)
+       {
+       }
+
+       public void visitSourceFile(SourceFile obj)
+       {
+       }
+
+       public void visitSynthetic(Synthetic obj)
+       {
+       }
+
+       public void visitUnknown(Unknown obj)
+       {
+       }
+
+       public void visitStackMap(StackMap obj)
+       {
+       }
+
+       public void visitStackMapEntry(StackMapEntry obj)
+       {
+       }
+
+       public void visitStackMapTable(StackMapTable obj)
+       {
+       }
+
+       public void visitStackMapTableEntry(StackMapTableEntry obj)
+       {
+       }
+
+       public void visitEnclosingMethod(EnclosingMethod obj)
+       {
+       }
+
+       public void visitLocalVariableTypeTable(LocalVariableTypeTable obj)
+       {
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/EnclosingMethod.java b/java/org/apache/tomcat/util/bcel/classfile/EnclosingMethod.java
new file mode 100755 (executable)
index 0000000..ab08c41
--- /dev/null
@@ -0,0 +1,87 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *    Andy Clement     initial implementation 
+ * ******************************************************************/
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This attribute exists for local or 
+ * anonymous classes and ... there can be only one.
+ */
+public class EnclosingMethod extends Attribute {
+       
+       // Pointer to the CONSTANT_Class_info structure representing the 
+       // innermost class that encloses the declaration of the current class.
+       private int classIndex;
+       
+       // If the current class is not immediately enclosed by a method or 
+       // constructor, then the value of the method_index item must be zero.  
+       // Otherwise, the value of the  method_index item must point to a 
+       // CONSTANT_NameAndType_info structure representing the name and the 
+       // type of a method in the class referenced by the class we point 
+       // to in the class_index.  *It is the compiler responsibility* to 
+       // ensure that the method identified by this index is the closest 
+       // lexically enclosing method that includes the local/anonymous class.
+       private int methodIndex;
+
+       // Ctors - and code to read an attribute in.
+       public EnclosingMethod(int nameIndex, int len, DataInput dis, ConstantPool cpool) throws IOException {
+               this(nameIndex, len, dis.readUnsignedShort(), dis.readUnsignedShort(), cpool);
+       }
+
+       private EnclosingMethod(int nameIndex, int len, int classIdx,int methodIdx, ConstantPool cpool) {
+           super(Constants.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool);
+           classIndex  = classIdx;
+           methodIndex = methodIdx;
+       }
+
+       public void accept(Visitor v) {
+         v.visitEnclosingMethod(this);
+       }
+
+       public Attribute copy(ConstantPool constant_pool) {
+               throw new RuntimeException("Not implemented yet!");
+               // is this next line sufficient?
+               // return (EnclosingMethod)clone();
+       }
+       
+       // Accessors
+       public final int getEnclosingClassIndex() { return classIndex; }  
+       public final int getEnclosingMethodIndex(){ return methodIndex;}
+       
+       public final void setEnclosingClassIndex(int idx) {classIndex = idx;}
+       public final void setEnclosingMethodIndex(int idx){methodIndex= idx;}
+
+       public final ConstantClass getEnclosingClass() {
+               ConstantClass c = 
+                       (ConstantClass)constant_pool.getConstant(classIndex,Constants.CONSTANT_Class);
+               return c;
+       }
+       
+       public final ConstantNameAndType getEnclosingMethod() {
+               if (methodIndex == 0) return null;
+               ConstantNameAndType nat = 
+                       (ConstantNameAndType)constant_pool.getConstant(methodIndex,Constants.CONSTANT_NameAndType);
+               return nat;
+       }
+
+    public final void dump(DataOutputStream file) throws IOException {
+           super.dump(file);
+           file.writeShort(classIndex);
+           file.writeShort(methodIndex);
+    }    
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/EnumElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/EnumElementValue.java
new file mode 100644 (file)
index 0000000..4d2c899
--- /dev/null
@@ -0,0 +1,62 @@
+package org.apache.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+public class EnumElementValue extends ElementValue
+{
+       // For enum types, these two indices point to the type and value
+       private int typeIdx;
+
+       private int valueIdx;
+
+       public EnumElementValue(int type, int typeIdx, int valueIdx,
+                       ConstantPool cpool)
+       {
+               super(type, cpool);
+               if (type != ENUM_CONSTANT)
+                       throw new RuntimeException(
+                                       "Only element values of type enum can be built with this ctor - type specified: " + type);
+               this.typeIdx = typeIdx;
+               this.valueIdx = valueIdx;
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ENUM_CONSTANT == 'e')
+               dos.writeShort(typeIdx); // u2
+               dos.writeShort(valueIdx); // u2
+       }
+
+       public String stringifyValue()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(valueIdx,
+                               Constants.CONSTANT_Utf8);
+               return cu8.getBytes();
+       }
+
+       public String getEnumTypeString()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(typeIdx,
+                               Constants.CONSTANT_Utf8);
+               return cu8.getBytes();// Utility.signatureToString(cu8.getBytes());
+       }
+
+       public String getEnumValueString()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(valueIdx,
+                               Constants.CONSTANT_Utf8);
+               return cu8.getBytes();
+       }
+
+       public int getValueIndex()
+       {
+               return valueIdx;
+       }
+
+       public int getTypeIndex()
+       {
+               return typeIdx;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ExceptionTable.java b/java/org/apache/tomcat/util/bcel/classfile/ExceptionTable.java
new file mode 100644 (file)
index 0000000..222478a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents the table of exceptions that are thrown by a
+ * method. This attribute may be used once per method.  The name of
+ * this class is <em>ExceptionTable</em> for historical reasons; The
+ * Java Virtual Machine Specification, Second Edition defines this
+ * attribute using the name <em>Exceptions</em> (which is inconsistent
+ * with the other classes).
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ */
+public final class ExceptionTable extends Attribute {
+
+    private int number_of_exceptions; // Table of indices into
+    private int[] exception_index_table; // constant pool
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public ExceptionTable(ExceptionTable c) {
+        this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index in constant pool
+     * @param length Content length in bytes
+     * @param exception_index_table Table of indices in constant pool
+     * @param constant_pool Array of constants
+     */
+    public ExceptionTable(int name_index, int length, int[] exception_index_table,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool);
+        setExceptionIndexTable(exception_index_table);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    ExceptionTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (int[]) null, constant_pool);
+        number_of_exceptions = file.readUnsignedShort();
+        exception_index_table = new int[number_of_exceptions];
+        for (int i = 0; i < number_of_exceptions; i++) {
+            exception_index_table[i] = file.readUnsignedShort();
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionTable(this);
+    }
+
+
+    /**
+     * Dump exceptions attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(number_of_exceptions);
+        for (int i = 0; i < number_of_exceptions; i++) {
+            file.writeShort(exception_index_table[i]);
+        }
+    }
+
+
+    /**
+     * @return Array of indices into constant pool of thrown exceptions.
+     */
+    public final int[] getExceptionIndexTable() {
+        return exception_index_table;
+    }
+
+
+    /**
+     * @return Length of exception table.
+     */
+    public final int getNumberOfExceptions() {
+        return number_of_exceptions;
+    }
+
+
+    /**
+     * @return class names of thrown exceptions
+     */
+    public final String[] getExceptionNames() {
+        String[] names = new String[number_of_exceptions];
+        for (int i = 0; i < number_of_exceptions; i++) {
+            names[i] = constant_pool.getConstantString(exception_index_table[i],
+                    Constants.CONSTANT_Class).replace('/', '.');
+        }
+        return names;
+    }
+
+
+    /**
+     * @param exception_index_table the list of exception indexes
+     * Also redefines number_of_exceptions according to table length.
+     */
+    public final void setExceptionIndexTable( int[] exception_index_table ) {
+        this.exception_index_table = exception_index_table;
+        number_of_exceptions = (exception_index_table == null) ? 0 : exception_index_table.length;
+    }
+
+
+    /**
+     * @return String representation, i.e., a list of thrown exceptions.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer();
+        String str;
+        for (int i = 0; i < number_of_exceptions; i++) {
+            str = constant_pool.getConstantString(exception_index_table[i],
+                    Constants.CONSTANT_Class);
+            buf.append(Utility.compactClassName(str, false));
+            if (i < number_of_exceptions - 1) {
+                buf.append(", ");
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        ExceptionTable c = (ExceptionTable) clone();
+        if (exception_index_table != null) {
+            c.exception_index_table = new int[exception_index_table.length];
+            System.arraycopy(exception_index_table, 0, c.exception_index_table, 0,
+                    exception_index_table.length);
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Field.java b/java/org/apache/tomcat/util/bcel/classfile/Field.java
new file mode 100644 (file)
index 0000000..3e907b8
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.generic.Type;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/**
+ * This class represents the field info structure, i.e., the representation 
+ * for a variable in the class. See JVM specification for details.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class Field extends FieldOrMethod {
+
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            Field THIS = (Field) o1;
+            Field THAT = (Field) o2;
+            return THIS.getName().equals(THAT.getName())
+                    && THIS.getSignature().equals(THAT.getSignature());
+        }
+
+
+        public int hashCode( Object o ) {
+            Field THIS = (Field) o;
+            return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+        }
+    };
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public Field(Field c) {
+        super(c);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     */
+    Field(DataInputStream file, ConstantPool constant_pool) throws IOException,
+            ClassFormatException {
+        super(file, constant_pool);
+    }
+
+
+    /**
+     * @param access_flags Access rights of field
+     * @param name_index Points to field name in constant pool
+     * @param signature_index Points to encoded signature
+     * @param attributes Collection of attributes
+     * @param constant_pool Array of constants
+     */
+    public Field(int access_flags, int name_index, int signature_index, Attribute[] attributes,
+            ConstantPool constant_pool) {
+        super(access_flags, name_index, signature_index, attributes, constant_pool);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitField(this);
+    }
+
+
+    /**
+     * @return constant value associated with this field (may be null)
+     */
+    public final ConstantValue getConstantValue() {
+        for (int i = 0; i < attributes_count; i++) {
+            if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) {
+                return (ConstantValue) attributes[i];
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Return string representation close to declaration format,
+     * `public static final short MAX = 100', e.g..
+     *
+     * @return String representation of field, including the signature.
+     */
+    public final String toString() {
+        String name, signature, access; // Short cuts to constant pool
+        // Get names from constant pool
+        access = Utility.accessToString(access_flags);
+        access = access.equals("") ? "" : (access + " ");
+        signature = Utility.signatureToString(getSignature());
+        name = getName();
+        StringBuffer buf = new StringBuffer(64);
+        buf.append(access).append(signature).append(" ").append(name);
+        ConstantValue cv = getConstantValue();
+        if (cv != null) {
+            buf.append(" = ").append(cv);
+        }
+        for (int i = 0; i < attributes_count; i++) {
+            Attribute a = attributes[i];
+            if (!(a instanceof ConstantValue)) {
+                buf.append(" [").append(a.toString()).append("]");
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this field
+     */
+    public final Field copy( ConstantPool _constant_pool ) {
+        return (Field) copy_(_constant_pool);
+    }
+
+
+    /**
+     * @return type of field
+     */
+    public Type getType() {
+        return Type.getReturnType(getSignature());
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two Field objects are said to be equal when
+     * their names and signatures are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the field's name XOR signature.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/FieldOrMethod.java b/java/org/apache/tomcat/util/bcel/classfile/FieldOrMethod.java
new file mode 100644 (file)
index 0000000..e4f7c85
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Signature;
+
+/** 
+ * Abstract super class for fields and methods.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node {
+
+    protected int name_index; // Points to field name in constant pool 
+    protected int signature_index; // Points to encoded signature
+    protected int attributes_count; // No. of attributes
+    protected Attribute[] attributes; // Collection of attributes
+    protected AnnotationEntry[] annotationEntries; // annotations defined on the field or method 
+    protected ConstantPool constant_pool;
+
+    private String signatureAttributeString = null;
+    private boolean searchedForSignatureAttribute = false;
+    
+
+    // Annotations are collected from certain attributes, don't do it more than necessary!
+    private boolean annotationsOutOfDate = true;
+
+    FieldOrMethod() {
+    }
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    protected FieldOrMethod(FieldOrMethod c) {
+        this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c
+                .getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     * @throws ClassFormatException
+     */
+    protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) throws IOException,
+            ClassFormatException {
+        this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null,
+                constant_pool);
+        attributes_count = file.readUnsignedShort();
+        attributes = new Attribute[attributes_count];
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i] = Attribute.readAttribute(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * @param access_flags Access rights of method
+     * @param name_index Points to field name in constant pool
+     * @param signature_index Points to encoded signature
+     * @param attributes Collection of attributes
+     * @param constant_pool Array of constants
+     */
+    protected FieldOrMethod(int access_flags, int name_index, int signature_index,
+            Attribute[] attributes, ConstantPool constant_pool) {
+        this.access_flags = access_flags;
+        this.name_index = name_index;
+        this.signature_index = signature_index;
+        this.constant_pool = constant_pool;
+        setAttributes(attributes);
+    }
+
+
+    /**
+     * Dump object to file stream on binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(access_flags);
+        file.writeShort(name_index);
+        file.writeShort(signature_index);
+        file.writeShort(attributes_count);
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Collection of object attributes.
+     */
+    public final Attribute[] getAttributes() {
+        return attributes;
+    }
+
+
+    /**
+     * @param attributes Collection of object attributes.
+     */
+    public final void setAttributes( Attribute[] attributes ) {
+        this.attributes = attributes;
+        attributes_count = (attributes == null) ? 0 : attributes.length;
+    }
+
+
+    /**
+     * @return Constant pool used by this object.
+     */
+    public final ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @param constant_pool Constant pool to be used for this object.
+     */
+    public final void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * @return Index in constant pool of object's name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /**
+     * @param name_index Index in constant pool of object's name.
+     */
+    public final void setNameIndex( int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * @return Index in constant pool of field signature.
+     */
+    public final int getSignatureIndex() {
+        return signature_index;
+    }
+
+
+    /**
+     * @param signature_index Index in constant pool of field signature.
+     */
+    public final void setSignatureIndex( int signature_index ) {
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * @return Name of object, i.e., method name or field name
+     */
+    public final String getName() {
+        ConstantUtf8 c;
+        c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return String representation of object's type signature (java style)
+     */
+    public final String getSignature() {
+        ConstantUtf8 c;
+        c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return deep copy of this field
+     */
+    protected FieldOrMethod copy_( ConstantPool _constant_pool ) {
+       FieldOrMethod c = null;
+
+        try {
+          c = (FieldOrMethod)clone();
+        } catch(CloneNotSupportedException e) {}
+
+        c.constant_pool    = constant_pool;
+        c.attributes       = new Attribute[attributes_count];
+
+        for(int i=0; i < attributes_count; i++)
+          c.attributes[i] = attributes[i].copy(constant_pool);
+
+        return c;
+    }
+    
+    /**
+        * Ensure we have unpacked any attributes that contain annotations.
+        * We don't remove these annotation attributes from the attributes list, they
+        * remain there.
+        */
+       private void ensureAnnotationsUpToDate()
+       {
+               if (annotationsOutOfDate)
+               {
+                       // Find attributes that contain annotation data
+                       Attribute[] attrs = getAttributes();
+                       List accumulatedAnnotations = new ArrayList();
+                       for (int i = 0; i < attrs.length; i++)
+                       {
+                               Attribute attribute = attrs[i];
+                               if (attribute instanceof Annotations)
+                               {
+                                       Annotations annotations = (Annotations) attribute;
+                                       for (int j = 0; j < annotations.getAnnotationEntries().length; j++)
+                                       {
+                                               accumulatedAnnotations.add(annotations
+                                                               .getAnnotationEntries()[j]);
+                                       }
+                               }
+                       }
+                       annotationEntries = (AnnotationEntry[]) accumulatedAnnotations
+                                       .toArray(new AnnotationEntry[accumulatedAnnotations.size()]);
+                       annotationsOutOfDate = false;
+               }
+       }
+
+       public AnnotationEntry[] getAnnotationEntries()
+       {
+               ensureAnnotationsUpToDate();
+               return annotationEntries;
+       }
+
+       public void addAnnotationEntry(AnnotationEntry a)
+       {
+               ensureAnnotationsUpToDate();
+               int len = annotationEntries.length;
+               AnnotationEntry[] newAnnotations = new AnnotationEntry[len + 1];
+               System.arraycopy(annotationEntries, 0, newAnnotations, 0, len);
+               newAnnotations[len] = a;
+               annotationEntries = newAnnotations;
+       }
+
+       /**
+        * Hunts for a signature attribute on the member and returns its contents.  So where the 'regular' signature
+        * may be (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector<Ljava/lang/String>;'
+        * Coded for performance - searches for the attribute only when requested - only searches for it once.
+        */
+       public final String getGenericSignature()
+       {
+               if (!searchedForSignatureAttribute)
+               {
+                       boolean found = false;
+                       for (int i = 0; !found && i < attributes_count; i++)
+                       {
+                               if (attributes[i] instanceof Signature)
+                               {
+                                       signatureAttributeString = ((Signature) attributes[i])
+                                                       .getSignature();
+                                       found = true;
+                               }
+                       }
+                       searchedForSignatureAttribute = true;
+               }
+               return signatureAttributeString;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/InnerClass.java b/java/org/apache/tomcat/util/bcel/classfile/InnerClass.java
new file mode 100644 (file)
index 0000000..f64f08f
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This class represents a inner class attribute, i.e., the class
+ * indices of the inner and outer classes, the name and the attributes
+ * of the inner class.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see InnerClasses
+ */
+public final class InnerClass implements Cloneable, Node, Serializable {
+
+    private int inner_class_index;
+    private int outer_class_index;
+    private int inner_name_index;
+    private int inner_access_flags;
+
+
+    /**
+     * Initialize from another object.
+     */
+    public InnerClass(InnerClass c) {
+        this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c
+                .getInnerAccessFlags());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    InnerClass(DataInput file) throws IOException {
+        this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
+                .readUnsignedShort());
+    }
+
+
+    /**
+     * @param inner_class_index Class index in constant pool of inner class
+     * @param outer_class_index Class index in constant pool of outer class
+     * @param inner_name_index  Name index in constant pool of inner class
+     * @param inner_access_flags Access flags of inner class
+     */
+    public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index,
+            int inner_access_flags) {
+        this.inner_class_index = inner_class_index;
+        this.outer_class_index = outer_class_index;
+        this.inner_name_index = inner_name_index;
+        this.inner_access_flags = inner_access_flags;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitInnerClass(this);
+    }
+
+
+    /**
+     * Dump inner class attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(inner_class_index);
+        file.writeShort(outer_class_index);
+        file.writeShort(inner_name_index);
+        file.writeShort(inner_access_flags);
+    }
+
+
+    /**
+     * @return access flags of inner class.
+     */
+    public final int getInnerAccessFlags() {
+        return inner_access_flags;
+    }
+
+
+    /**
+     * @return class index of inner class.
+     */
+    public final int getInnerClassIndex() {
+        return inner_class_index;
+    }
+
+
+    /**
+     * @return name index of inner class.
+     */
+    public final int getInnerNameIndex() {
+        return inner_name_index;
+    }
+
+
+    /**
+     * @return class index of outer class.
+     */
+    public final int getOuterClassIndex() {
+        return outer_class_index;
+    }
+
+
+    /**
+     * @param inner_access_flags access flags for this inner class
+     */
+    public final void setInnerAccessFlags( int inner_access_flags ) {
+        this.inner_access_flags = inner_access_flags;
+    }
+
+
+    /**
+     * @param inner_class_index index into the constant pool for this class
+     */
+    public final void setInnerClassIndex( int inner_class_index ) {
+        this.inner_class_index = inner_class_index;
+    }
+
+
+    /**
+     * @param inner_name_index index into the constant pool for this class's name
+     */
+    public final void setInnerNameIndex( int inner_name_index ) {
+        this.inner_name_index = inner_name_index;
+    }
+
+
+    /**
+     * @param outer_class_index index into the constant pool for the owning class
+     */
+    public final void setOuterClassIndex( int outer_class_index ) {
+        this.outer_class_index = outer_class_index;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", "
+                + inner_name_index + ", " + inner_access_flags + ")";
+    }
+
+
+    /**
+     * @return Resolved string representation
+     */
+    public final String toString( ConstantPool constant_pool ) {
+        String inner_class_name, outer_class_name, inner_name, access;
+        inner_class_name = constant_pool.getConstantString(inner_class_index,
+                Constants.CONSTANT_Class);
+        inner_class_name = Utility.compactClassName(inner_class_name);
+        if (outer_class_index != 0) {
+            outer_class_name = constant_pool.getConstantString(outer_class_index,
+                    Constants.CONSTANT_Class);
+            outer_class_name = Utility.compactClassName(outer_class_name);
+        } else {
+            outer_class_name = "<not a member>";
+        }
+        if (inner_name_index != 0) {
+            inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index,
+                    Constants.CONSTANT_Utf8)).getBytes();
+        } else {
+            inner_name = "<anonymous>";
+        }
+        access = Utility.accessToString(inner_access_flags, true);
+        access = access.equals("") ? "" : (access + " ");
+        return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \""
+                + inner_name + "\")";
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public InnerClass copy() {
+        try {
+            return (InnerClass) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/InnerClasses.java b/java/org/apache/tomcat/util/bcel/classfile/InnerClasses.java
new file mode 100644 (file)
index 0000000..5f46f54
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and denotes that this class
+ * is an Inner class of another.
+ * to the source file of this class.
+ * It is instantiated from the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class InnerClasses extends Attribute {
+
+    private InnerClass[] inner_classes;
+    private int number_of_classes;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public InnerClasses(InnerClasses c) {
+        this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param inner_classes array of inner classes attributes
+     * @param constant_pool Array of constants
+     */
+    public InnerClasses(int name_index, int length, InnerClass[] inner_classes,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool);
+        setInnerClasses(inner_classes);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     *
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (InnerClass[]) null, constant_pool);
+        number_of_classes = file.readUnsignedShort();
+        inner_classes = new InnerClass[number_of_classes];
+        for (int i = 0; i < number_of_classes; i++) {
+            inner_classes[i] = new InnerClass(file);
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitInnerClasses(this);
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(number_of_classes);
+        for (int i = 0; i < number_of_classes; i++) {
+            inner_classes[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return array of inner class "records"
+     */
+    public final InnerClass[] getInnerClasses() {
+        return inner_classes;
+    }
+
+
+    /**
+     * @param inner_classes the array of inner classes
+     */
+    public final void setInnerClasses( InnerClass[] inner_classes ) {
+        this.inner_classes = inner_classes;
+        number_of_classes = (inner_classes == null) ? 0 : inner_classes.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < number_of_classes; i++) {
+            buf.append(inner_classes[i].toString(constant_pool)).append("\n");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        InnerClasses c = (InnerClasses) clone();
+        c.inner_classes = new InnerClass[number_of_classes];
+        for (int i = 0; i < number_of_classes; i++) {
+            c.inner_classes[i] = inner_classes[i].copy();
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java b/java/org/apache/tomcat/util/bcel/classfile/JavaClass.java
new file mode 100644 (file)
index 0000000..84298d0
--- /dev/null
@@ -0,0 +1,933 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.generic.Type;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+import org.apache.tomcat.util.bcel.util.ClassQueue;
+import org.apache.tomcat.util.bcel.util.SyntheticRepository;
+
+/**
+ * Represents a Java class, i.e., the data structures, constant pool,
+ * fields, methods and commands contained in a Java .class file.
+ * See <a href="ftp://java.sun.com/docs/specs/">JVM specification</a> for details.
+ * The intent of this class is to represent a parsed or otherwise existing
+ * class file.  Those interested in programatically generating classes
+ * should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
+
+ * @version $Id$
+ * @see org.apache.tomcat.util.bcel.generic.ClassGen
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable {
+
+    private String file_name;
+    private String package_name;
+    private String source_file_name = "<Unknown>";
+    private int class_name_index;
+    private int superclass_name_index;
+    private String class_name;
+    private String superclass_name;
+    private int major, minor; // Compiler version
+    private ConstantPool constant_pool; // Constant pool
+    private int[] interfaces; // implemented interfaces
+    private String[] interface_names;
+    private Field[] fields; // Fields, i.e., variables of class
+    private Method[] methods; // methods defined in the class
+    private Attribute[] attributes; // attributes defined in the class
+    private AnnotationEntry[] annotations;   // annotations defined on the class
+    private byte source = HEAP; // Generated in memory
+    private boolean isAnonymous = false;
+    private boolean isNested = false;
+    private boolean computedNestedTypeStatus = false;
+    public static final byte HEAP = 1;
+    public static final byte FILE = 2;
+    public static final byte ZIP = 3;
+    static boolean debug = false; // Debugging on/off
+    static char sep = '/'; // directory separator
+    
+    //  Annotations are collected from certain attributes, don't do it more than necessary!
+    private boolean annotationsOutOfDate = true;
+    
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            JavaClass THIS = (JavaClass) o1;
+            JavaClass THAT = (JavaClass) o2;
+            return THIS.getClassName().equals(THAT.getClassName());
+        }
+
+
+        public int hashCode( Object o ) {
+            JavaClass THIS = (JavaClass) o;
+            return THIS.getClassName().hashCode();
+        }
+    };
+    /**
+     * In cases where we go ahead and create something,
+     * use the default SyntheticRepository, because we
+     * don't know any better.
+     */
+    private transient org.apache.tomcat.util.bcel.util.Repository repository = SyntheticRepository
+            .getInstance();
+
+
+    /**
+     * Constructor gets all contents as arguments.
+     *
+     * @param class_name_index Index into constant pool referencing a
+     * ConstantClass that represents this class.
+     * @param superclass_name_index Index into constant pool referencing a
+     * ConstantClass that represents this class's superclass.
+     * @param file_name File name
+     * @param major Major compiler version
+     * @param minor Minor compiler version
+     * @param access_flags Access rights defined by bit flags
+     * @param constant_pool Array of constants
+     * @param interfaces Implemented interfaces
+     * @param fields Class fields
+     * @param methods Class methods
+     * @param attributes Class attributes
+     * @param source Read from file or generated in memory?
+     */
+    public JavaClass(int class_name_index, int superclass_name_index, String file_name, int major,
+            int minor, int access_flags, ConstantPool constant_pool, int[] interfaces,
+            Field[] fields, Method[] methods, Attribute[] attributes, byte source) {
+        if (interfaces == null) {
+            interfaces = new int[0];
+        }
+        if (attributes == null) {
+            attributes = new Attribute[0];
+        }
+        if (fields == null) {
+            fields = new Field[0];
+        }
+        if (methods == null) {
+            methods = new Method[0];
+        }
+        this.class_name_index = class_name_index;
+        this.superclass_name_index = superclass_name_index;
+        this.file_name = file_name;
+        this.major = major;
+        this.minor = minor;
+        this.access_flags = access_flags;
+        this.constant_pool = constant_pool;
+        this.interfaces = interfaces;
+        this.fields = fields;
+        this.methods = methods;
+        this.attributes = attributes;
+        annotationsOutOfDate = true;
+        this.source = source;
+        // Get source file name if available
+        for (int i = 0; i < attributes.length; i++) {
+            if (attributes[i] instanceof SourceFile) {
+                source_file_name = ((SourceFile) attributes[i]).getSourceFileName();
+                break;
+            }
+        }
+        /* According to the specification the following entries must be of type
+         * `ConstantClass' but we check that anyway via the 
+         * `ConstPool.getConstant' method.
+         */
+        class_name = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class);
+        class_name = Utility.compactClassName(class_name, false);
+        int index = class_name.lastIndexOf('.');
+        if (index < 0) {
+            package_name = "";
+        } else {
+            package_name = class_name.substring(0, index);
+        }
+        if (superclass_name_index > 0) {
+            // May be zero -> class is java.lang.Object
+            superclass_name = constant_pool.getConstantString(superclass_name_index,
+                    Constants.CONSTANT_Class);
+            superclass_name = Utility.compactClassName(superclass_name, false);
+        } else {
+            superclass_name = "java.lang.Object";
+        }
+        interface_names = new String[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++) {
+            String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
+            interface_names[i] = Utility.compactClassName(str, false);
+        }
+    }
+
+
+    /**
+     * Constructor gets all contents as arguments.
+     *
+     * @param class_name_index Class name
+     * @param superclass_name_index Superclass name
+     * @param file_name File name
+     * @param major Major compiler version
+     * @param minor Minor compiler version
+     * @param access_flags Access rights defined by bit flags
+     * @param constant_pool Array of constants
+     * @param interfaces Implemented interfaces
+     * @param fields Class fields
+     * @param methods Class methods
+     * @param attributes Class attributes
+     */
+    public JavaClass(int class_name_index, int superclass_name_index, String file_name, int major,
+            int minor, int access_flags, ConstantPool constant_pool, int[] interfaces,
+            Field[] fields, Method[] methods, Attribute[] attributes) {
+        this(class_name_index, superclass_name_index, file_name, major, minor, access_flags,
+                constant_pool, interfaces, fields, methods, attributes, HEAP);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitJavaClass(this);
+    }
+
+
+    /* Print debug information depending on `JavaClass.debug'
+     */
+    static final void Debug( String str ) {
+        if (debug) {
+            System.out.println(str);
+        }
+    }
+
+
+    /** 
+     * Dump class to a file.
+     *
+     * @param file Output file
+     * @throws IOException
+     */
+    public void dump( File file ) throws IOException {
+        String parent = file.getParent();
+        if (parent != null) {
+            File dir = new File(parent);
+            dir.mkdirs();
+        }
+        DataOutputStream dos = null;
+        try {
+            dos = new DataOutputStream(new FileOutputStream(file));
+            dump(dos);
+        } finally {
+            if (dos != null) {
+                dos.close();
+            }
+        }
+    }
+
+
+    /** 
+     * Dump class to a file named file_name.
+     *
+     * @param _file_name Output file name
+     * @exception IOException
+     */
+    public void dump( String _file_name ) throws IOException {
+        dump(new File(_file_name));
+    }
+
+
+    /**
+     * @return class in binary format
+     */
+    public byte[] getBytes() {
+        ByteArrayOutputStream s = new ByteArrayOutputStream();
+        DataOutputStream ds = new DataOutputStream(s);
+        try {
+            dump(ds);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                ds.close();
+            } catch (IOException e2) {
+                e2.printStackTrace();
+            }
+        }
+        return s.toByteArray();
+    }
+
+
+    /**
+     * Dump Java class to output stream in binary format.
+     *
+     * @param file Output stream
+     * @exception IOException
+     */
+    public void dump( OutputStream file ) throws IOException {
+        dump(new DataOutputStream(file));
+    }
+
+
+    /**
+     * Dump Java class to output stream in binary format.
+     *
+     * @param file Output stream
+     * @exception IOException
+     */
+    public void dump( DataOutputStream file ) throws IOException {
+        file.writeInt(0xcafebabe);
+        file.writeShort(minor);
+        file.writeShort(major);
+        constant_pool.dump(file);
+        file.writeShort(access_flags);
+        file.writeShort(class_name_index);
+        file.writeShort(superclass_name_index);
+        file.writeShort(interfaces.length);
+        for (int i = 0; i < interfaces.length; i++) {
+            file.writeShort(interfaces[i]);
+        }
+        file.writeShort(fields.length);
+        for (int i = 0; i < fields.length; i++) {
+            fields[i].dump(file);
+        }
+        file.writeShort(methods.length);
+        for (int i = 0; i < methods.length; i++) {
+            methods[i].dump(file);
+        }
+        if (attributes != null) {
+            file.writeShort(attributes.length);
+            for (int i = 0; i < attributes.length; i++) {
+                attributes[i].dump(file);
+            }
+        } else {
+            file.writeShort(0);
+        }
+        file.flush();
+    }
+
+
+    /**
+     * @return Attributes of the class.
+     */
+    public Attribute[] getAttributes() {
+        return attributes;
+    }
+    
+    public AnnotationEntry[] getAnnotationEntries() {
+       if (annotationsOutOfDate) { 
+               // Find attributes that contain annotation data
+               Attribute[] attrs = getAttributes();
+               List accumulatedAnnotations = new ArrayList();
+               for (int i = 0; i < attrs.length; i++) {
+                       Attribute attribute = attrs[i];
+                       if (attribute instanceof Annotations) {                         
+                               Annotations runtimeAnnotations = (Annotations)attribute;
+                               for(int j = 0; j < runtimeAnnotations.getAnnotationEntries().length; j++)
+                                       accumulatedAnnotations.add(runtimeAnnotations.getAnnotationEntries()[j]);
+                       }
+               }
+               annotations = (AnnotationEntry[])accumulatedAnnotations.toArray(new AnnotationEntry[accumulatedAnnotations.size()]);
+               annotationsOutOfDate = false;
+       }
+       return annotations;
+      }
+    /**
+     * @return Class name.
+     */
+    public String getClassName() {
+        return class_name;
+    }
+
+
+    /**
+     * @return Package name.
+     */
+    public String getPackageName() {
+        return package_name;
+    }
+
+
+    /**
+     * @return Class name index.
+     */
+    public int getClassNameIndex() {
+        return class_name_index;
+    }
+
+
+    /**
+     * @return Constant pool.
+     */
+    public ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @return Fields, i.e., variables of the class. Like the JVM spec
+     * mandates for the classfile format, these fields are those specific to
+     * this class, and not those of the superclass or superinterfaces.
+     */
+    public Field[] getFields() {
+        return fields;
+    }
+
+
+    /**
+     * @return File name of class, aka SourceFile attribute value
+     */
+    public String getFileName() {
+        return file_name;
+    }
+
+
+    /**
+     * @return Names of implemented interfaces.
+     */
+    public String[] getInterfaceNames() {
+        return interface_names;
+    }
+
+
+    /**
+     * @return Indices in constant pool of implemented interfaces.
+     */
+    public int[] getInterfaceIndices() {
+        return interfaces;
+    }
+
+
+    /**
+     * @return Major number of class file version.
+     */
+    public int getMajor() {
+        return major;
+    }
+
+
+    /**
+     * @return Methods of the class.
+     */
+    public Method[] getMethods() {
+        return methods;
+    }
+
+
+    /**
+     * @return A org.apache.tomcat.util.bcel.classfile.Method corresponding to
+     * java.lang.reflect.Method if any
+     */
+    public Method getMethod( java.lang.reflect.Method m ) {
+        for (int i = 0; i < methods.length; i++) {
+            Method method = methods[i];
+            if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers())
+                    && Type.getSignature(m).equals(method.getSignature())) {
+                return method;
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @return Minor number of class file version.
+     */
+    public int getMinor() {
+        return minor;
+    }
+
+
+    /**
+     * @return sbsolute path to file where this class was read from
+     */
+    public String getSourceFileName() {
+        return source_file_name;
+    }
+
+
+    /**
+     * @return Superclass name.
+     */
+    public String getSuperclassName() {
+        return superclass_name;
+    }
+
+
+    /**
+     * @return Class name index.
+     */
+    public int getSuperclassNameIndex() {
+        return superclass_name_index;
+    }
+
+    static {
+        // Debugging ... on/off
+        debug = Boolean.getBoolean("JavaClass.debug");
+        // Get path separator either / or \ usually
+        String _sep = System.getProperty("file.separator");
+        if (_sep != null) {
+            try {
+                JavaClass.sep = _sep.charAt(0);
+            } catch (StringIndexOutOfBoundsException e) {
+            } // Never reached
+        }
+    }
+
+
+    /**
+     * @param attributes .
+     */
+    public void setAttributes( Attribute[] attributes ) {
+        this.attributes = attributes;
+    }
+
+
+    /**
+     * @param class_name .
+     */
+    public void setClassName( String class_name ) {
+        this.class_name = class_name;
+    }
+
+
+    /**
+     * @param class_name_index .
+     */
+    public void setClassNameIndex( int class_name_index ) {
+        this.class_name_index = class_name_index;
+    }
+
+
+    /**
+     * @param constant_pool .
+     */
+    public void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * @param fields .
+     */
+    public void setFields( Field[] fields ) {
+        this.fields = fields;
+    }
+
+
+    /**
+     * Set File name of class, aka SourceFile attribute value
+     */
+    public void setFileName( String file_name ) {
+        this.file_name = file_name;
+    }
+
+
+    /**
+     * @param interface_names .
+     */
+    public void setInterfaceNames( String[] interface_names ) {
+        this.interface_names = interface_names;
+    }
+
+
+    /**
+     * @param interfaces .
+     */
+    public void setInterfaces( int[] interfaces ) {
+        this.interfaces = interfaces;
+    }
+
+
+    /**
+     * @param major .
+     */
+    public void setMajor( int major ) {
+        this.major = major;
+    }
+
+
+    /**
+     * @param methods .
+     */
+    public void setMethods( Method[] methods ) {
+        this.methods = methods;
+    }
+
+
+    /**
+     * @param minor .
+     */
+    public void setMinor( int minor ) {
+        this.minor = minor;
+    }
+
+
+    /**
+     * Set absolute path to file this class was read from.
+     */
+    public void setSourceFileName( String source_file_name ) {
+        this.source_file_name = source_file_name;
+    }
+
+
+    /**
+     * @param superclass_name .
+     */
+    public void setSuperclassName( String superclass_name ) {
+        this.superclass_name = superclass_name;
+    }
+
+
+    /**
+     * @param superclass_name_index .
+     */
+    public void setSuperclassNameIndex( int superclass_name_index ) {
+        this.superclass_name_index = superclass_name_index;
+    }
+
+
+    /**
+     * @return String representing class contents.
+     */
+    public String toString() {
+        String access = Utility.accessToString(access_flags, true);
+        access = access.equals("") ? "" : (access + " ");
+        StringBuffer buf = new StringBuffer(128);
+        buf.append(access).append(Utility.classOrInterface(access_flags)).append(" ").append(
+                class_name).append(" extends ").append(
+                Utility.compactClassName(superclass_name, false)).append('\n');
+        int size = interfaces.length;
+        if (size > 0) {
+            buf.append("implements\t\t");
+            for (int i = 0; i < size; i++) {
+                buf.append(interface_names[i]);
+                if (i < size - 1) {
+                    buf.append(", ");
+                }
+            }
+            buf.append('\n');
+        }
+        buf.append("filename\t\t").append(file_name).append('\n');
+        buf.append("compiled from\t\t").append(source_file_name).append('\n');
+        buf.append("compiler version\t").append(major).append(".").append(minor).append('\n');
+        buf.append("access flags\t\t").append(access_flags).append('\n');
+        buf.append("constant pool\t\t").append(constant_pool.getLength()).append(" entries\n");
+        buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n");
+        if (attributes.length > 0) {
+            buf.append("\nAttribute(s):\n");
+            for (int i = 0; i < attributes.length; i++) {
+                buf.append(indent(attributes[i]));
+            }
+        }
+        AnnotationEntry[] annotations = getAnnotationEntries();
+        if (annotations!=null && annotations.length>0) {
+               buf.append("\nAnnotation(s):\n");
+               for (int i=0; i<annotations.length; i++) 
+                       buf.append(indent(annotations[i]));
+        }
+        if (fields.length > 0) {
+            buf.append("\n").append(fields.length).append(" fields:\n");
+            for (int i = 0; i < fields.length; i++) {
+                buf.append("\t").append(fields[i]).append('\n');
+            }
+        }
+        if (methods.length > 0) {
+            buf.append("\n").append(methods.length).append(" methods:\n");
+            for (int i = 0; i < methods.length; i++) {
+                buf.append("\t").append(methods[i]).append('\n');
+            }
+        }
+        return buf.toString();
+    }
+
+
+    private static final String indent( Object obj ) {
+        StringTokenizer tok = new StringTokenizer(obj.toString(), "\n");
+        StringBuffer buf = new StringBuffer();
+        while (tok.hasMoreTokens()) {
+            buf.append("\t").append(tok.nextToken()).append("\n");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this class
+     */
+    public JavaClass copy() {
+        JavaClass c = null;
+        try {
+            c = (JavaClass) clone();
+            c.constant_pool = constant_pool.copy();
+            c.interfaces = (int[]) interfaces.clone();
+            c.interface_names = (String[]) interface_names.clone();
+            c.fields = new Field[fields.length];
+            for (int i = 0; i < fields.length; i++) {
+                c.fields[i] = fields[i].copy(c.constant_pool);
+            }
+            c.methods = new Method[methods.length];
+            for (int i = 0; i < methods.length; i++) {
+                c.methods[i] = methods[i].copy(c.constant_pool);
+            }
+            c.attributes = new Attribute[attributes.length];
+            for (int i = 0; i < attributes.length; i++) {
+                c.attributes[i] = attributes[i].copy(c.constant_pool);
+            }
+        } catch (CloneNotSupportedException e) {
+        }
+        return c;
+    }
+
+
+    public final boolean isSuper() {
+        return (access_flags & Constants.ACC_SUPER) != 0;
+    }
+
+
+    public final boolean isClass() {
+        return (access_flags & Constants.ACC_INTERFACE) == 0;
+    }
+    
+    public final boolean isAnonymous() {
+         computeNestedTypeStatus();
+         return this.isAnonymous;
+    }
+    
+    public final boolean isNested() {
+         computeNestedTypeStatus();
+         return this.isNested;
+    }
+    
+    private final void computeNestedTypeStatus() {
+         if (computedNestedTypeStatus) return;
+         for (int i = 0; i < this.attributes.length; i++) {
+                       if (this.attributes[i] instanceof InnerClasses) {
+                               InnerClass[] innerClasses = ((InnerClasses) this.attributes[i]).getInnerClasses();
+                               for (int j = 0; j < innerClasses.length; j++) {
+                                       boolean innerClassAttributeRefersToMe = false;
+                                       String inner_class_name = constant_pool.getConstantString(innerClasses[j].getInnerClassIndex(),
+                                                      Constants.CONSTANT_Class);
+                                       inner_class_name = Utility.compactClassName(inner_class_name);
+                                       if (inner_class_name.equals(getClassName())) {
+                                               innerClassAttributeRefersToMe = true;
+                                       }
+                                       if (innerClassAttributeRefersToMe) {
+                                               this.isNested = true;
+                                               if (innerClasses[j].getInnerNameIndex() == 0) {
+                                                       this.isAnonymous = true;
+                                               }
+                                       }
+                               }
+                       }
+         }
+         this.computedNestedTypeStatus = true;
+    }
+
+
+    /** @return returns either HEAP (generated), FILE, or ZIP
+     */
+    public final byte getSource() {
+        return source;
+    }
+
+
+    /********************* New repository functionality *********************/
+    /**
+     * Gets the ClassRepository which holds its definition. By default
+     * this is the same as SyntheticRepository.getInstance();
+     */
+    public org.apache.tomcat.util.bcel.util.Repository getRepository() {
+        return repository;
+    }
+
+
+    /**
+     * Sets the ClassRepository which loaded the JavaClass.
+     * Should be called immediately after parsing is done.
+     */
+    public void setRepository( org.apache.tomcat.util.bcel.util.Repository repository ) {
+        this.repository = repository;
+    }
+
+
+    /** Equivalent to runtime "instanceof" operator.
+     *
+     * @return true if this JavaClass is derived from the super class
+     * @throws ClassNotFoundException if superclasses or superinterfaces
+     *   of this object can't be found
+     */
+    public final boolean instanceOf( JavaClass super_class ) throws ClassNotFoundException {
+        if (this.equals(super_class)) {
+            return true;
+        }
+        JavaClass[] super_classes = getSuperClasses();
+        for (int i = 0; i < super_classes.length; i++) {
+            if (super_classes[i].equals(super_class)) {
+                return true;
+            }
+        }
+        if (super_class.isInterface()) {
+            return implementationOf(super_class);
+        }
+        return false;
+    }
+
+
+    /**
+     * @return true, if this class is an implementation of interface inter
+     * @throws ClassNotFoundException if superclasses or superinterfaces
+     *   of this class can't be found
+     */
+    public boolean implementationOf( JavaClass inter ) throws ClassNotFoundException {
+        if (!inter.isInterface()) {
+            throw new IllegalArgumentException(inter.getClassName() + " is no interface");
+        }
+        if (this.equals(inter)) {
+            return true;
+        }
+        JavaClass[] super_interfaces = getAllInterfaces();
+        for (int i = 0; i < super_interfaces.length; i++) {
+            if (super_interfaces[i].equals(inter)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**
+     * @return the superclass for this JavaClass object, or null if this
+     * is java.lang.Object
+     * @throws ClassNotFoundException if the superclass can't be found
+     */
+    public JavaClass getSuperClass() throws ClassNotFoundException {
+        if ("java.lang.Object".equals(getClassName())) {
+            return null;
+        }
+        return repository.loadClass(getSuperclassName());
+    }
+
+
+    /**
+     * @return list of super classes of this class in ascending order, i.e.,
+     * java.lang.Object is always the last element
+     * @throws ClassNotFoundException if any of the superclasses can't be found
+     */
+    public JavaClass[] getSuperClasses() throws ClassNotFoundException {
+        JavaClass clazz = this;
+        List allSuperClasses = new ArrayList();
+        for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) {
+            allSuperClasses.add(clazz);
+        }
+        return (JavaClass[]) allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]);
+    }
+
+
+    /**
+     * Get interfaces directly implemented by this JavaClass.
+     */
+    public JavaClass[] getInterfaces() throws ClassNotFoundException {
+        String[] _interfaces = getInterfaceNames();
+        JavaClass[] classes = new JavaClass[_interfaces.length];
+        for (int i = 0; i < _interfaces.length; i++) {
+            classes[i] = repository.loadClass(_interfaces[i]);
+        }
+        return classes;
+    }
+
+
+    /**
+     * Get all interfaces implemented by this JavaClass (transitively).
+     */
+    public JavaClass[] getAllInterfaces() throws ClassNotFoundException {
+        ClassQueue queue = new ClassQueue();
+        Set allInterfaces = new TreeSet();
+        queue.enqueue(this);
+        while (!queue.empty()) {
+            JavaClass clazz = queue.dequeue();
+            JavaClass souper = clazz.getSuperClass();
+            JavaClass[] _interfaces = clazz.getInterfaces();
+            if (clazz.isInterface()) {
+                allInterfaces.add(clazz);
+            } else {
+                if (souper != null) {
+                    queue.enqueue(souper);
+                }
+            }
+            for (int i = 0; i < _interfaces.length; i++) {
+                queue.enqueue(_interfaces[i]);
+            }
+        }
+        return (JavaClass[]) allInterfaces.toArray(new JavaClass[allInterfaces.size()]);
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two JavaClass objects are said to be equal when
+     * their class names are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return the natural ordering of two JavaClasses.
+     * This ordering is based on the class name
+     */
+    public int compareTo( Object obj ) {
+        return getClassName().compareTo(((JavaClass) obj).getClassName());
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the class name.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/LineNumber.java b/java/org/apache/tomcat/util/bcel/classfile/LineNumber.java
new file mode 100644 (file)
index 0000000..3dfd64e
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * This class represents a (PC offset, line number) pair, i.e., a line number in
+ * the source that corresponds to a relative address in the byte code. This
+ * is used for debugging purposes.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     LineNumberTable
+ */
+public final class LineNumber implements Cloneable, Node, Serializable {
+
+    private int start_pc; // Program Counter (PC) corresponds to line
+    private int line_number; // number in source file
+
+
+    /**
+     * Initialize from another object.
+     */
+    public LineNumber(LineNumber c) {
+        this(c.getStartPC(), c.getLineNumber());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    LineNumber(DataInput file) throws IOException {
+        this(file.readUnsignedShort(), file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param start_pc Program Counter (PC) corresponds to
+     * @param line_number line number in source file
+     */
+    public LineNumber(int start_pc, int line_number) {
+        this.start_pc = start_pc;
+        this.line_number = line_number;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLineNumber(this);
+    }
+
+
+    /**
+     * Dump line number/pc pair to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(start_pc);
+        file.writeShort(line_number);
+    }
+
+
+    /**
+     * @return Corresponding source line
+     */
+    public final int getLineNumber() {
+        return line_number;
+    }
+
+
+    /**
+     * @return PC in code
+     */
+    public final int getStartPC() {
+        return start_pc;
+    }
+
+
+    /**
+     * @param line_number the source line number
+     */
+    public final void setLineNumber( int line_number ) {
+        this.line_number = line_number;
+    }
+
+
+    /**
+     * @param start_pc the pc for this line number
+     */
+    public final void setStartPC( int start_pc ) {
+        this.start_pc = start_pc;
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return "LineNumber(" + start_pc + ", " + line_number + ")";
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public LineNumber copy() {
+        try {
+            return (LineNumber) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/LineNumberTable.java b/java/org/apache/tomcat/util/bcel/classfile/LineNumberTable.java
new file mode 100644 (file)
index 0000000..d0cdedf
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a table of line numbers for debugging
+ * purposes. This attribute is used by the <em>Code</em> attribute. It
+ * contains pairs of PCs and line numbers.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ * @see LineNumber
+ */
+public final class LineNumberTable extends Attribute {
+
+    private int line_number_table_length;
+    private LineNumber[] line_number_table; // Table of line/numbers pairs
+
+
+    /*
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public LineNumberTable(LineNumberTable c) {
+        this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
+    }
+
+
+    /*
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param line_number_table Table of line/numbers pairs
+     * @param constant_pool Array of constants
+     */
+    public LineNumberTable(int name_index, int length, LineNumber[] line_number_table,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool);
+        setLineNumberTable(line_number_table);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (LineNumber[]) null, constant_pool);
+        line_number_table_length = (file.readUnsignedShort());
+        line_number_table = new LineNumber[line_number_table_length];
+        for (int i = 0; i < line_number_table_length; i++) {
+            line_number_table[i] = new LineNumber(file);
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLineNumberTable(this);
+    }
+
+
+    /**
+     * Dump line number table attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(line_number_table_length);
+        for (int i = 0; i < line_number_table_length; i++) {
+            line_number_table[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Array of (pc offset, line number) pairs.
+     */
+    public final LineNumber[] getLineNumberTable() {
+        return line_number_table;
+    }
+
+
+    /**
+     * @param line_number_table the line number entries for this table
+     */
+    public final void setLineNumberTable( LineNumber[] line_number_table ) {
+        this.line_number_table = line_number_table;
+        line_number_table_length = (line_number_table == null) ? 0 : line_number_table.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer();
+        StringBuffer line = new StringBuffer();
+        String newLine = System.getProperty("line.separator", "\n");
+        for (int i = 0; i < line_number_table_length; i++) {
+            line.append(line_number_table[i].toString());
+            if (i < line_number_table_length - 1) {
+                line.append(", ");
+            }
+            if (line.length() > 72) {
+                line.append(newLine);
+                buf.append(line.toString());
+                line.setLength(0);
+            }
+        }
+        buf.append(line);
+        return buf.toString();
+    }
+
+
+    /**
+     * Map byte code positions to source code lines.
+     *
+     * @param pos byte code offset
+     * @return corresponding line in source code
+     */
+    public int getSourceLine( int pos ) {
+        int l = 0, r = line_number_table_length - 1;
+        if (r < 0) {
+            return -1;
+        }
+        int min_index = -1, min = -1;
+        /* Do a binary search since the array is ordered.
+         */
+        do {
+            int i = (l + r) / 2;
+            int j = line_number_table[i].getStartPC();
+            if (j == pos) {
+                return line_number_table[i].getLineNumber();
+            } else if (pos < j) {
+                r = i - 1;
+            } else {
+                l = i + 1;
+            }
+            /* If exact match can't be found (which is the most common case)
+             * return the line number that corresponds to the greatest index less
+             * than pos.
+             */
+            if (j < pos && j > min) {
+                min = j;
+                min_index = i;
+            }
+        } while (l <= r);
+        /* It's possible that we did not find any valid entry for the bytecode
+         * offset we were looking for.
+         */
+        if (min_index < 0) {
+            return -1;
+        }
+        return line_number_table[min_index].getLineNumber();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        LineNumberTable c = (LineNumberTable) clone();
+        c.line_number_table = new LineNumber[line_number_table_length];
+        for (int i = 0; i < line_number_table_length; i++) {
+            c.line_number_table[i] = line_number_table[i].copy();
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+
+
+    public final int getTableLength() {
+        return line_number_table_length;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/LocalVariable.java b/java/org/apache/tomcat/util/bcel/classfile/LocalVariable.java
new file mode 100644 (file)
index 0000000..45f5f00
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a local variable within a method. It contains its
+ * scope, name, signature and index on the method's frame.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     LocalVariableTable
+ */
+public final class LocalVariable implements Constants, Cloneable, Node, Serializable {
+
+    private int start_pc; // Range in which the variable is valid
+    private int length;
+    private int name_index; // Index in constant pool of variable name
+    private int signature_index; // Index of variable signature
+    private int index; /* Variable is `index'th local variable on
+     * this method's frame.
+     */
+    private ConstantPool constant_pool;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public LocalVariable(LocalVariable c) {
+        this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(),
+                c.getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    LocalVariable(DataInput file, ConstantPool constant_pool) throws IOException {
+        this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
+                .readUnsignedShort(), file.readUnsignedShort(), constant_pool);
+    }
+
+
+    /**
+     * @param start_pc Range in which the variable
+     * @param length ... is valid
+     * @param name_index Index in constant pool of variable name
+     * @param signature_index Index of variable's signature
+     * @param index Variable is `index'th local variable on the method's frame
+     * @param constant_pool Array of constants
+     */
+    public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index,
+            ConstantPool constant_pool) {
+        this.start_pc = start_pc;
+        this.length = length;
+        this.name_index = name_index;
+        this.signature_index = signature_index;
+        this.index = index;
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLocalVariable(this);
+    }
+
+
+    /**
+     * Dump local variable to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(start_pc);
+        file.writeShort(length);
+        file.writeShort(name_index);
+        file.writeShort(signature_index);
+        file.writeShort(index);
+    }
+
+
+    /**
+     * @return Constant pool used by this object.
+     */
+    public final ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @return Variable is valid within getStartPC() .. getStartPC()+getLength()
+     */
+    public final int getLength() {
+        return length;
+    }
+
+
+    /**
+     * @return Variable name.
+     */
+    public final String getName() {
+        ConstantUtf8 c;
+        c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return Index in constant pool of variable name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /**
+     * @return Signature.
+     */
+    public final String getSignature() {
+        ConstantUtf8 c;
+        c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return Index in constant pool of variable signature.
+     */
+    public final int getSignatureIndex() {
+        return signature_index;
+    }
+
+
+    /**
+     * @return index of register where variable is stored
+     */
+    public final int getIndex() {
+        return index;
+    }
+
+
+    /**
+     * @return Start of range where he variable is valid
+     */
+    public final int getStartPC() {
+        return start_pc;
+    }
+
+
+    /**
+     * @param constant_pool Constant pool to be used for this object.
+     */
+    public final void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * @param length the length of this local variable
+     */
+    public final void setLength( int length ) {
+        this.length = length;
+    }
+
+
+    /**
+     * @param name_index the index into the constant pool for the name of this variable
+     */
+    public final void setNameIndex( int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * @param signature_index the index into the constant pool for the signature of this variable
+     */
+    public final void setSignatureIndex( int signature_index ) {
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * @param index the index in the local variable table of this variable
+     */
+    public final void setIndex( int index ) {
+        this.index = index;
+    }
+
+
+    /**
+     * @param start_pc Specify range where the local variable is valid.
+     */
+    public final void setStartPC( int start_pc ) {
+        this.start_pc = start_pc;
+    }
+
+
+    /**
+     * @return string representation.
+     */
+    public final String toString() {
+        String name = getName(), signature = Utility.signatureToString(getSignature());
+        return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = "
+                + index + ":" + signature + " " + name + ")";
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public LocalVariable copy() {
+        try {
+            return (LocalVariable) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/LocalVariableTable.java b/java/org/apache/tomcat/util/bcel/classfile/LocalVariableTable.java
new file mode 100644 (file)
index 0000000..c699457
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents colection of local variables in a
+ * method. This attribute is contained in the <em>Code</em> attribute.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ * @see LocalVariable
+ */
+public class LocalVariableTable extends Attribute {
+
+    private int local_variable_table_length; // Table of local
+    private LocalVariable[] local_variable_table; // variables
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public LocalVariableTable(LocalVariableTable c) {
+        this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to `LocalVariableTable'
+     * @param length Content length in bytes
+     * @param local_variable_table Table of local variables
+     * @param constant_pool Array of constants
+     */
+    public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool);
+        setLocalVariableTable(local_variable_table);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (LocalVariable[]) null, constant_pool);
+        local_variable_table_length = (file.readUnsignedShort());
+        local_variable_table = new LocalVariable[local_variable_table_length];
+        for (int i = 0; i < local_variable_table_length; i++) {
+            local_variable_table[i] = new LocalVariable(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLocalVariableTable(this);
+    }
+
+
+    /**
+     * Dump local variable table attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(local_variable_table_length);
+        for (int i = 0; i < local_variable_table_length; i++) {
+            local_variable_table[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Array of local variables of method.
+     */
+    public final LocalVariable[] getLocalVariableTable() {
+        return local_variable_table;
+    }
+
+
+    /** 
+     * @return first matching variable using index
+     * 
+     * @param index the variable slot
+     * 
+     * @return the first LocalVariable that matches the slot or null if not found
+     * 
+     * @deprecated since 5.2 because multiple variables can share the
+     *             same slot, use getLocalVariable(int index, int pc) instead.
+     */
+    public final LocalVariable getLocalVariable( int index ) {
+        for (int i = 0; i < local_variable_table_length; i++) {
+            if (local_variable_table[i].getIndex() == index) {
+                return local_variable_table[i];
+            }
+        }
+        return null;
+    }
+
+
+    /** 
+     * @return matching variable using index when variable is used at supplied pc
+     * 
+     * @param index the variable slot
+     * @param pc the current pc that this variable is alive
+     * 
+     * @return the LocalVariable that matches or null if not found
+     */
+    public final LocalVariable getLocalVariable( int index, int pc ) {
+        for (int i = 0; i < local_variable_table_length; i++) {
+            if (local_variable_table[i].getIndex() == index) {
+                int start_pc = local_variable_table[i].getStartPC();
+                int end_pc = start_pc + local_variable_table[i].getLength();
+                if ((pc >= start_pc) && (pc <= end_pc)) {
+                    return local_variable_table[i];
+                }
+            }
+        }
+        return null;
+    }
+
+
+    public final void setLocalVariableTable( LocalVariable[] local_variable_table ) {
+        this.local_variable_table = local_variable_table;
+        local_variable_table_length = (local_variable_table == null)
+                ? 0
+                : local_variable_table.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < local_variable_table_length; i++) {
+            buf.append(local_variable_table[i].toString());
+            if (i < local_variable_table_length - 1) {
+                buf.append('\n');
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        LocalVariableTable c = (LocalVariableTable) clone();
+        c.local_variable_table = new LocalVariable[local_variable_table_length];
+        for (int i = 0; i < local_variable_table_length; i++) {
+            c.local_variable_table[i] = local_variable_table[i].copy();
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+
+
+    public final int getTableLength() {
+        return local_variable_table_length;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/LocalVariableTypeTable.java b/java/org/apache/tomcat/util/bcel/classfile/LocalVariableTypeTable.java
new file mode 100755 (executable)
index 0000000..eed0b54
--- /dev/null
@@ -0,0 +1,135 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *    Andy Clement     initial implementation 
+ *    Heavily based on LocalVariableTable
+ * ******************************************************************/
+package org.apache.tomcat.util.bcel.classfile;
+
+
+import  org.apache.tomcat.util.bcel.Constants;
+import  java.io.*;
+
+// The new table is used when generic types are about...
+
+//LocalVariableTable_attribute {
+//        u2 attribute_name_index;
+//        u4 attribute_length;
+//        u2 local_variable_table_length;
+//        {  u2 start_pc;
+//           u2 length;
+//           u2 name_index;
+//           u2 descriptor_index;
+//           u2 index;
+//        } local_variable_table[local_variable_table_length];
+//      }
+
+//LocalVariableTypeTable_attribute {
+//    u2 attribute_name_index;
+//    u4 attribute_length;
+//    u2 local_variable_type_table_length;
+//    { 
+//      u2 start_pc;
+//      u2 length;
+//      u2 name_index;
+//      u2 signature_index;
+//      u2 index;
+//    } local_variable_type_table[local_variable_type_table_length];
+//  }
+// J5TODO: Needs some testing !
+public class LocalVariableTypeTable extends Attribute {
+  private int             local_variable_type_table_length; // Table of local
+  private LocalVariable[] local_variable_type_table;        // variables
+
+  public LocalVariableTypeTable(LocalVariableTypeTable c) {
+    this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(),
+        c.getConstantPool());
+  }
+
+  public LocalVariableTypeTable(int name_index, int length,
+                           LocalVariable[] local_variable_table,
+                           ConstantPool    constant_pool)
+  {
+    super(Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool);
+    setLocalVariableTable(local_variable_table);
+  }    
+
+  LocalVariableTypeTable(int nameIdx, int len, DataInputStream dis,ConstantPool cpool) throws IOException {
+    this(nameIdx, len, (LocalVariable[])null, cpool);
+
+    local_variable_type_table_length = (dis.readUnsignedShort());
+    local_variable_type_table = new LocalVariable[local_variable_type_table_length];
+
+    for(int i=0; i < local_variable_type_table_length; i++)
+      local_variable_type_table[i] = new LocalVariable(dis, cpool);
+  }
+
+  public void accept(Visitor v) {
+    v.visitLocalVariableTypeTable(this);
+  }
+
+  public final void dump(DataOutputStream file) throws IOException
+  {
+    super.dump(file);
+    file.writeShort(local_variable_type_table_length);
+    for(int i=0; i < local_variable_type_table_length; i++)
+      local_variable_type_table[i].dump(file);
+  }
+
+  public final LocalVariable[] getLocalVariableTypeTable() {
+    return local_variable_type_table;
+  }    
+
+  public final LocalVariable getLocalVariable(int index) {
+    for(int i=0; i < local_variable_type_table_length; i++)
+      if(local_variable_type_table[i].getIndex() == index)
+       return local_variable_type_table[i];
+
+    return null;
+  }
+
+  public final void setLocalVariableTable(LocalVariable[] local_variable_table)
+  {
+    this.local_variable_type_table = local_variable_table;
+    local_variable_type_table_length = (local_variable_table == null)? 0 :
+      local_variable_table.length;
+  }
+
+  /**
+   * @return String representation.
+   */ 
+  public final String toString() {
+    StringBuffer buf = new StringBuffer();
+
+    for(int i=0; i < local_variable_type_table_length; i++) {
+      buf.append(local_variable_type_table[i].toString());
+
+      if(i < local_variable_type_table_length - 1) buf.append('\n');
+    }
+
+    return buf.toString();
+  }
+
+  /**
+   * @return deep copy of this attribute
+   */
+  public Attribute copy(ConstantPool constant_pool) {
+    LocalVariableTypeTable c = (LocalVariableTypeTable)clone();
+
+    c.local_variable_type_table = new LocalVariable[local_variable_type_table_length];
+    for(int i=0; i < local_variable_type_table_length; i++)
+      c.local_variable_type_table[i] = local_variable_type_table[i].copy();
+
+    c.constant_pool = constant_pool;
+    return c;
+  }
+
+  public final int getTableLength() { return local_variable_type_table_length; }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Method.java b/java/org/apache/tomcat/util/bcel/classfile/Method.java
new file mode 100644 (file)
index 0000000..91e4341
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.generic.Type;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/**
+ * This class represents the method info structure, i.e., the representation 
+ * for a method in the class. See JVM specification for details.
+ * A method has access flags, a name, a signature and a number of attributes.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class Method extends FieldOrMethod {
+
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            Method THIS = (Method) o1;
+            Method THAT = (Method) o2;
+            return THIS.getName().equals(THAT.getName())
+                    && THIS.getSignature().equals(THAT.getSignature());
+        }
+
+
+        public int hashCode( Object o ) {
+            Method THIS = (Method) o;
+            return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+        }
+    };
+
+
+    /**
+     * Empty constructor, all attributes have to be defined via `setXXX'
+     * methods. Use at your own risk.
+     */
+    public Method() {
+    }
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public Method(Method c) {
+        super(c);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     * @throws ClassFormatException
+     */
+    Method(DataInputStream file, ConstantPool constant_pool) throws IOException,
+            ClassFormatException {
+        super(file, constant_pool);
+    }
+
+
+    /**
+     * @param access_flags Access rights of method
+     * @param name_index Points to field name in constant pool
+     * @param signature_index Points to encoded signature
+     * @param attributes Collection of attributes
+     * @param constant_pool Array of constants
+     */
+    public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes,
+            ConstantPool constant_pool) {
+        super(access_flags, name_index, signature_index, attributes, constant_pool);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitMethod(this);
+    }
+
+
+    /**
+     * @return Code attribute of method, if any
+     */
+    public final Code getCode() {
+        for (int i = 0; i < attributes_count; i++) {
+            if (attributes[i] instanceof Code) {
+                return (Code) attributes[i];
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * @return ExceptionTable attribute of method, if any, i.e., list all
+     * exceptions the method may throw not exception handlers!
+     */
+    public final ExceptionTable getExceptionTable() {
+        for (int i = 0; i < attributes_count; i++) {
+            if (attributes[i] instanceof ExceptionTable) {
+                return (ExceptionTable) attributes[i];
+            }
+        }
+        return null;
+    }
+
+
+    /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded
+     * to the Code atribute.
+     */
+    public final LocalVariableTable getLocalVariableTable() {
+        Code code = getCode();
+        if (code == null) {
+            return null;
+        }
+        return code.getLocalVariableTable();
+    }
+
+
+    /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
+     * to the Code atribute.
+     */
+    public final LineNumberTable getLineNumberTable() {
+        Code code = getCode();
+        if (code == null) {
+            return null;
+        }
+        return code.getLineNumberTable();
+    }
+
+
+    /**
+     * Return string representation close to declaration format,
+     * `public static void main(String[] args) throws IOException', e.g.
+     *
+     * @return String representation of the method.
+     */
+    public final String toString() {
+        ConstantUtf8 c;
+        String name, signature, access; // Short cuts to constant pool
+        StringBuffer buf;
+        access = Utility.accessToString(access_flags);
+        // Get name and signature from constant pool
+        c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
+        signature = c.getBytes();
+        c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
+        name = c.getBytes();
+        signature = Utility.methodSignatureToString(signature, name, access, true,
+                getLocalVariableTable());
+        buf = new StringBuffer(signature);
+        for (int i = 0; i < attributes_count; i++) {
+            Attribute a = attributes[i];
+            if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
+                buf.append(" [").append(a.toString()).append("]");
+            }
+        }
+        ExceptionTable e = getExceptionTable();
+        if (e != null) {
+            String str = e.toString();
+            if (!str.equals("")) {
+                buf.append("\n\t\tthrows ").append(str);
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this method
+     */
+    public final Method copy( ConstantPool _constant_pool ) {
+        return (Method) copy_(_constant_pool);
+    }
+
+
+    /**
+     * @return return type of method
+     */
+    public Type getReturnType() {
+        return Type.getReturnType(getSignature());
+    }
+
+
+    /**
+     * @return array of method argument types
+     */
+    public Type[] getArgumentTypes() {
+        return Type.getArgumentTypes(getSignature());
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two method objects are said to be equal when
+     * their names and signatures are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the method's name XOR signature.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Node.java b/java/org/apache/tomcat/util/bcel/classfile/Node.java
new file mode 100644 (file)
index 0000000..83e63d4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/**
+ * Denote class to have an accept method();
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface Node {
+
+    public void accept( Visitor obj );
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/PMGClass.java b/java/org/apache/tomcat/util/bcel/classfile/PMGClass.java
new file mode 100644 (file)
index 0000000..f104eea
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a reference
+ * to a PMG attribute.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class PMGClass extends Attribute {
+
+    private int pmg_class_index, pmg_index;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public PMGClass(PMGClass c) {
+        this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), c
+                .getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    PMGClass(int name_index, int length, DataInput file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), constant_pool);
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param pmg_index index in constant pool for source file name
+     * @param pmg_class_index Index in constant pool to CONSTANT_Utf8
+     * @param constant_pool Array of constants
+     */
+    public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index,
+            ConstantPool constant_pool) {
+        super(Constants.ATTR_PMG, name_index, length, constant_pool);
+        this.pmg_index = pmg_index;
+        this.pmg_class_index = pmg_class_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        System.err.println("Visiting non-standard PMGClass object");
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(pmg_index);
+        file.writeShort(pmg_class_index);
+    }
+
+
+    /**
+     * @return Index in constant pool of source file name.
+     */
+    public final int getPMGClassIndex() {
+        return pmg_class_index;
+    }
+
+
+    /**
+     * @param pmg_class_index
+     */
+    public final void setPMGClassIndex( int pmg_class_index ) {
+        this.pmg_class_index = pmg_class_index;
+    }
+
+
+    /**
+     * @return Index in constant pool of source file name.
+     */
+    public final int getPMGIndex() {
+        return pmg_index;
+    }
+
+
+    /**
+     * @param pmg_index
+     */
+    public final void setPMGIndex( int pmg_index ) {
+        this.pmg_index = pmg_index;
+    }
+
+
+    /**
+     * @return PMG name.
+     */
+    public final String getPMGName() {
+        ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_index,
+                Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return PMG class name.
+     */
+    public final String getPMGClassName() {
+        ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_class_index,
+                Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")";
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        return (PMGClass) clone();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotationEntry.java b/java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotationEntry.java
new file mode 100644 (file)
index 0000000..5005587
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents one parameter annotation in the parameter annotation table
+ * 
+ * @version $Id: ParameterAnnotationEntry
+ * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class ParameterAnnotationEntry implements Node, Constants {
+
+    private int annotation_table_length;
+    private AnnotationEntry[] annotation_table;
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    ParameterAnnotationEntry(DataInputStream file, ConstantPool constant_pool) throws IOException {
+        annotation_table_length = (file.readUnsignedShort());
+        annotation_table = new AnnotationEntry[annotation_table_length];
+        for (int i = 0; i < annotation_table_length; i++) {
+//              TODO isRuntimeVisible
+            annotation_table[i] = AnnotationEntry.read(file, constant_pool, false);
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        //         v.visitParameterAnnotationEntry(this);
+    }
+
+
+    /**
+     * @return the number of annotation entries in this parameter annotation
+     */
+    public final int getNumAnnotations() {
+        return annotation_table_length;
+    }
+
+
+    /**
+     * returns the array of annotation entries in this annotation
+     */
+    public AnnotationEntry[] getAnnotationEntries() {
+        return annotation_table;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotations.java b/java/org/apache/tomcat/util/bcel/classfile/ParameterAnnotations.java
new file mode 100644 (file)
index 0000000..abfb593
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * base class for parameter annotations
+ * 
+ * @version $Id: ParameterAnnotations
+ * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public abstract class ParameterAnnotations extends Attribute {
+
+    private int num_parameters;
+    private ParameterAnnotationEntry[] parameter_annotation_table; // Table of parameter annotations
+
+
+    /**
+     * @param parameter_annotation_type the subclass type of the parameter annotation
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     */
+    ParameterAnnotations(byte parameter_annotation_type, int name_index, int length,
+            DataInputStream file, ConstantPool constant_pool) throws IOException {
+        this(parameter_annotation_type, name_index, length, (ParameterAnnotationEntry[]) null,
+                constant_pool);
+        num_parameters = (file.readUnsignedByte());
+        parameter_annotation_table = new ParameterAnnotationEntry[num_parameters];
+        for (int i = 0; i < num_parameters; i++) {
+            parameter_annotation_table[i] = new ParameterAnnotationEntry(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * @param parameter_annotation_type the subclass type of the parameter annotation
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param parameter_annotation_table the actual parameter annotations
+     * @param constant_pool Array of constants
+     */
+    public ParameterAnnotations(byte parameter_annotation_type, int name_index, int length,
+            ParameterAnnotationEntry[] parameter_annotation_table, ConstantPool constant_pool) {
+        super(parameter_annotation_type, name_index, length, constant_pool);
+        setParameterAnnotationTable(parameter_annotation_table);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        //         v.visitParameterAnnotation(this);
+    }
+
+
+    /**
+     * @param parameter_annotation_table the entries to set in this parameter annotation
+     */
+    public final void setParameterAnnotationTable(
+            ParameterAnnotationEntry[] parameter_annotation_table ) {
+        this.parameter_annotation_table = parameter_annotation_table;
+        num_parameters = (parameter_annotation_table == null)
+                ? 0
+                : parameter_annotation_table.length;
+    }
+
+
+    /**
+     * @return the parameter annotation entry table
+     */
+    public final ParameterAnnotationEntry[] getParameterAnnotationTable() {
+        return parameter_annotation_table;
+    }
+
+
+    /**
+     * returns the array of parameter annotation entries in this parameter annotation
+     */
+    public ParameterAnnotationEntry[] getParameterAnnotationEntries() {
+        return parameter_annotation_table;
+    }
+
+
+    /**
+     * @return the number of parameter annotation entries in this parameter annotation
+     */
+    public final int getNumParameterAnnotation() {
+        return num_parameters;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleAnnotations.java b/java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleAnnotations.java
new file mode 100644 (file)
index 0000000..9a57021
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents an annotation that is represented in the class file but is not
+ * provided to the JVM.
+ * 
+ * @version $Id: RuntimeInvisibleAnnotations
+ * @author <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class RuntimeInvisibleAnnotations extends Annotations
+{
+       /**
+        * @param name_index
+        *            Index pointing to the name <em>Code</em>
+        * @param length
+        *            Content length in bytes
+        * @param file
+        *            Input stream
+        * @param constant_pool
+        *            Array of constants
+        */
+       RuntimeInvisibleAnnotations(int name_index, int length,
+                       DataInputStream file, ConstantPool constant_pool)
+                       throws IOException
+       {
+               super(Constants.ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS, name_index, length,
+                               file, constant_pool, false);
+       }
+
+       /**
+        * @return deep copy of this attribute
+        */
+       public Attribute copy(ConstantPool constant_pool)
+       {
+               Annotations c = (Annotations) clone();
+               return c;
+       }
+
+       public final void dump(DataOutputStream dos) throws IOException
+       {
+               super.dump(dos);
+               writeAnnotations(dos);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleParameterAnnotations.java b/java/org/apache/tomcat/util/bcel/classfile/RuntimeInvisibleParameterAnnotations.java
new file mode 100644 (file)
index 0000000..ef841e4
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents a parameter annotation that is represented in the class file
+ * but is not provided to the JVM.
+ * 
+ * @version $Id: RuntimeInvisibleParameterAnnotations
+ * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class RuntimeInvisibleParameterAnnotations extends ParameterAnnotations {
+
+    /**
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     */
+    RuntimeInvisibleParameterAnnotations(int name_index, int length, DataInputStream file,
+            ConstantPool constant_pool) throws IOException {
+        super(Constants.ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS, name_index, length, file,
+                constant_pool);
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool constant_pool ) {
+        Annotations c = (Annotations) clone();
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleAnnotations.java b/java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleAnnotations.java
new file mode 100644 (file)
index 0000000..b52c69a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents an annotation that is represented in the class file and is
+ * provided to the JVM.
+ * 
+ * @version $Id: RuntimeVisibleAnnotations
+ * @author <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class RuntimeVisibleAnnotations extends Annotations
+{
+       /**
+        * @param name_index
+        *            Index pointing to the name <em>Code</em>
+        * @param length
+        *            Content length in bytes
+        * @param file
+        *            Input stream
+        * @param constant_pool
+        *            Array of constants
+        */
+       public RuntimeVisibleAnnotations(int name_index, int length,
+                       DataInputStream file, ConstantPool constant_pool)
+                       throws IOException
+       {
+               super(Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS, name_index, length,
+                               file, constant_pool, true);
+       }
+
+       /**
+        * @return deep copy of this attribute
+        */
+       public Attribute copy(ConstantPool constant_pool)
+       {
+               Annotations c = (Annotations) clone();
+               return c;
+       }
+
+       public final void dump(DataOutputStream dos) throws IOException
+       {
+               super.dump(dos);
+               writeAnnotations(dos);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleParameterAnnotations.java b/java/org/apache/tomcat/util/bcel/classfile/RuntimeVisibleParameterAnnotations.java
new file mode 100644 (file)
index 0000000..de22c4b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * represents a parameter annotation that is represented in the class file
+ * and is provided to the JVM.
+ * 
+ * @version $Id: RuntimeVisibleParameterAnnotations
+ * @author  <A HREF="mailto:dbrosius@qis.net">D. Brosius</A>
+ * @since 5.3
+ */
+public class RuntimeVisibleParameterAnnotations extends ParameterAnnotations {
+
+    /**
+     * @param name_index Index pointing to the name <em>Code</em>
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     */
+    RuntimeVisibleParameterAnnotations(int name_index, int length, DataInputStream file,
+            ConstantPool constant_pool) throws IOException {
+        super(Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, name_index, length, file,
+                constant_pool);
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool constant_pool ) {
+        Annotations c = (Annotations) clone();
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Signature.java b/java/org/apache/tomcat/util/bcel/classfile/Signature.java
new file mode 100644 (file)
index 0000000..9748032
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a reference
+ * to a GJ attribute.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class Signature extends Attribute {
+
+    private int signature_index;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public Signature(Signature c) {
+        this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    Signature(int name_index, int length, DataInput file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, file.readUnsignedShort(), constant_pool);
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param signature_index Index in constant pool to CONSTANT_Utf8
+     * @param constant_pool Array of constants
+     */
+    public Signature(int name_index, int length, int signature_index, ConstantPool constant_pool) {
+        super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        //System.err.println("Visiting non-standard Signature object");
+        v.visitSignature(this);
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(signature_index);
+    }
+
+
+    /**
+     * @return Index in constant pool of source file name.
+     */
+    public final int getSignatureIndex() {
+        return signature_index;
+    }
+
+
+    /**
+     * @param signature_index the index info the constant pool of this signature
+     */
+    public final void setSignatureIndex( int signature_index ) {
+        this.signature_index = signature_index;
+    }
+
+
+    /**
+     * @return GJ signature.
+     */
+    public final String getSignature() {
+        ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(signature_index,
+                Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+    /**
+     * Extends ByteArrayInputStream to make 'unreading' chars possible.
+     */
+    private static final class MyByteArrayInputStream extends ByteArrayInputStream {
+
+        MyByteArrayInputStream(String data) {
+            super(data.getBytes());
+        }
+
+
+        final int mark() {
+            return pos;
+        }
+
+
+        final String getData() {
+            return new String(buf);
+        }
+
+
+        final void reset( int p ) {
+            pos = p;
+        }
+
+
+        final void unread() {
+            if (pos > 0) {
+                pos--;
+            }
+        }
+    }
+
+
+    private static boolean identStart( int ch ) {
+        return ch == 'T' || ch == 'L';
+    }
+
+
+    private static final void matchIdent( MyByteArrayInputStream in, StringBuffer buf ) {
+        int ch;
+        if ((ch = in.read()) == -1) {
+            throw new RuntimeException("Illegal signature: " + in.getData()
+                    + " no ident, reaching EOF");
+        }
+        //System.out.println("return from ident:" + (char)ch);
+        if (!identStart(ch)) {
+            StringBuffer buf2 = new StringBuffer();
+            int count = 1;
+            while (Character.isJavaIdentifierPart((char) ch)) {
+                buf2.append((char) ch);
+                count++;
+                ch = in.read();
+            }
+            if (ch == ':') { // Ok, formal parameter
+                in.skip("Ljava/lang/Object".length());
+                buf.append(buf2);
+                ch = in.read();
+                in.unread();
+                //System.out.println("so far:" + buf2 + ":next:" +(char)ch);
+            } else {
+                for (int i = 0; i < count; i++) {
+                    in.unread();
+                }
+            }
+            return;
+        }
+        StringBuffer buf2 = new StringBuffer();
+        ch = in.read();
+        do {
+            buf2.append((char) ch);
+            ch = in.read();
+            //System.out.println("within ident:"+ (char)ch);
+        } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/')));
+        buf.append(buf2.toString().replace('/', '.'));
+        //System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
+        if (ch != -1) {
+            in.unread();
+        }
+    }
+
+
+    private static final void matchGJIdent( MyByteArrayInputStream in, StringBuffer buf ) {
+        int ch;
+        matchIdent(in, buf);
+        ch = in.read();
+        if ((ch == '<') || ch == '(') { // Parameterized or method
+            //System.out.println("Enter <");
+            buf.append((char) ch);
+            matchGJIdent(in, buf);
+            while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
+                if (ch == -1) {
+                    throw new RuntimeException("Illegal signature: " + in.getData()
+                            + " reaching EOF");
+                }
+                //System.out.println("Still no >");
+                buf.append(", ");
+                in.unread();
+                matchGJIdent(in, buf); // Recursive call
+            }
+            //System.out.println("Exit >");
+            buf.append((char) ch);
+        } else {
+            in.unread();
+        }
+        ch = in.read();
+        if (identStart(ch)) {
+            in.unread();
+            matchGJIdent(in, buf);
+        } else if (ch == ')') {
+            in.unread();
+            return;
+        } else if (ch != ';') {
+            throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch);
+        }
+    }
+
+
+    public static String translate( String s ) {
+        //System.out.println("Sig:" + s);
+        StringBuffer buf = new StringBuffer();
+        matchGJIdent(new MyByteArrayInputStream(s), buf);
+        return buf.toString();
+    }
+
+
+    public static final boolean isFormalParameterList( String s ) {
+        return s.startsWith("<") && (s.indexOf(':') > 0);
+    }
+
+
+    public static final boolean isActualParameterList( String s ) {
+        return s.startsWith("L") && s.endsWith(">;");
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        String s = getSignature();
+        return "Signature(" + s + ")";
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        return (Signature) clone();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/SimpleElementValue.java b/java/org/apache/tomcat/util/bcel/classfile/SimpleElementValue.java
new file mode 100644 (file)
index 0000000..8373fee
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+public class SimpleElementValue extends ElementValue
+{
+       private int index;
+
+       public SimpleElementValue(int type, int index, ConstantPool cpool)
+       {
+               super(type, cpool);
+               this.index = index;
+       }
+
+       /**
+        * @return Value entry index in the cpool
+        */
+       public int getIndex()
+       {
+               return index;
+       }
+
+       public void setIndex(int index)
+       {
+               this.index = index;
+       }
+
+       public String getValueString()
+       {
+               if (type != STRING)
+                       throw new RuntimeException(
+                                       "Dont call getValueString() on a non STRING ElementValue");
+               ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(getIndex(),
+                               Constants.CONSTANT_Utf8);
+               return c.getBytes();
+       }
+
+       public int getValueInt()
+       {
+               if (type != PRIMITIVE_INT)
+                       throw new RuntimeException(
+                                       "Dont call getValueString() on a non STRING ElementValue");
+               ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(),
+                               Constants.CONSTANT_Integer);
+               return c.getBytes();
+       }
+
+       public byte getValueByte()
+       {
+               if (type != PRIMITIVE_BYTE)
+                       throw new RuntimeException(
+                                       "Dont call getValueByte() on a non BYTE ElementValue");
+               ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(),
+                               Constants.CONSTANT_Integer);
+               return (byte) c.getBytes();
+       }
+
+       public char getValueChar()
+       {
+               if (type != PRIMITIVE_CHAR)
+                       throw new RuntimeException(
+                                       "Dont call getValueChar() on a non CHAR ElementValue");
+               ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(),
+                               Constants.CONSTANT_Integer);
+               return (char) c.getBytes();
+       }
+
+       public long getValueLong()
+       {
+               if (type != PRIMITIVE_LONG)
+                       throw new RuntimeException(
+                                       "Dont call getValueLong() on a non LONG ElementValue");
+               ConstantLong j = (ConstantLong) cpool.getConstant(getIndex());
+               return j.getBytes();
+       }
+
+       public float getValueFloat()
+       {
+               if (type != PRIMITIVE_FLOAT)
+                       throw new RuntimeException(
+                                       "Dont call getValueFloat() on a non FLOAT ElementValue");
+               ConstantFloat f = (ConstantFloat) cpool.getConstant(getIndex());
+               return f.getBytes();
+       }
+
+       public double getValueDouble()
+       {
+               if (type != PRIMITIVE_DOUBLE)
+                       throw new RuntimeException(
+                                       "Dont call getValueDouble() on a non DOUBLE ElementValue");
+               ConstantDouble d = (ConstantDouble) cpool.getConstant(getIndex());
+               return d.getBytes();
+       }
+
+       public boolean getValueBoolean()
+       {
+               if (type != PRIMITIVE_BOOLEAN)
+                       throw new RuntimeException(
+                                       "Dont call getValueBoolean() on a non BOOLEAN ElementValue");
+               ConstantInteger bo = (ConstantInteger) cpool.getConstant(getIndex());
+               return (bo.getBytes() != 0);
+       }
+
+       public short getValueShort()
+       {
+               if (type != PRIMITIVE_SHORT)
+                       throw new RuntimeException(
+                                       "Dont call getValueShort() on a non SHORT ElementValue");
+               ConstantInteger s = (ConstantInteger) cpool.getConstant(getIndex());
+               return (short) s.getBytes();
+       }
+
+       public String toString()
+       {
+               return stringifyValue();
+       }
+
+       // Whatever kind of value it is, return it as a string
+       public String stringifyValue()
+       {
+               switch (type)
+               {
+               case PRIMITIVE_INT:
+                       ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Integer);
+                       return Integer.toString(c.getBytes());
+               case PRIMITIVE_LONG:
+                       ConstantLong j = (ConstantLong) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Long);
+                       return Long.toString(j.getBytes());
+               case PRIMITIVE_DOUBLE:
+                       ConstantDouble d = (ConstantDouble) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Double);
+                       return Double.toString(d.getBytes());
+               case PRIMITIVE_FLOAT:
+                       ConstantFloat f = (ConstantFloat) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Float);
+                       return Float.toString(f.getBytes());
+               case PRIMITIVE_SHORT:
+                       ConstantInteger s = (ConstantInteger) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Integer);
+                       return Integer.toString(s.getBytes());
+               case PRIMITIVE_BYTE:
+                       ConstantInteger b = (ConstantInteger) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Integer);
+                       return Integer.toString(b.getBytes());
+               case PRIMITIVE_CHAR:
+                       ConstantInteger ch = (ConstantInteger) cpool.getConstant(
+                                       getIndex(), Constants.CONSTANT_Integer);
+                       return String.valueOf((char)ch.getBytes());
+               case PRIMITIVE_BOOLEAN:
+                       ConstantInteger bo = (ConstantInteger) cpool.getConstant(
+                                       getIndex(), Constants.CONSTANT_Integer);
+                       if (bo.getBytes() == 0)
+                               return "false";
+                       if (bo.getBytes() != 0)
+                               return "true";
+               case STRING:
+                       ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(getIndex(),
+                                       Constants.CONSTANT_Utf8);
+                       return cu8.getBytes();
+               default:
+                       throw new RuntimeException(
+                                       "SimpleElementValue class does not know how to stringify type "
+                                                       + type);
+               }
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 kind of value
+               switch (type)
+               {
+               case PRIMITIVE_INT:
+               case PRIMITIVE_BYTE:
+               case PRIMITIVE_CHAR:
+               case PRIMITIVE_FLOAT:
+               case PRIMITIVE_LONG:
+               case PRIMITIVE_BOOLEAN:
+               case PRIMITIVE_SHORT:
+               case PRIMITIVE_DOUBLE:
+               case STRING:
+                       dos.writeShort(getIndex());
+                       break;
+               default:
+                       throw new RuntimeException(
+                                       "SimpleElementValue doesnt know how to write out type "
+                                                       + type);
+               }
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/SourceFile.java b/java/org/apache/tomcat/util/bcel/classfile/SourceFile.java
new file mode 100644 (file)
index 0000000..61abf40
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and represents a reference
+ * to the source file of this class.  At most one SourceFile attribute
+ * should appear per classfile.  The intention of this class is that it is
+ * instantiated from the <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class SourceFile extends Attribute {
+
+    private int sourcefile_index;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public SourceFile(SourceFile c) {
+        this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool());
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    SourceFile(int name_index, int length, DataInput file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, file.readUnsignedShort(), constant_pool);
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8, which
+     * should represent the string "SourceFile".
+     * @param length Content length in bytes, the value should be 2.
+     * @param constant_pool The constant pool that this attribute is
+     * associated with.
+     * @param sourcefile_index Index in constant pool to CONSTANT_Utf8.  This
+     * string will be interpreted as the name of the file from which this
+     * class was compiled.  It will not be interpreted as indicating the name
+     * of the directory contqining the file or an absolute path; this
+     * information has to be supplied the consumer of this attribute - in
+     * many cases, the JVM.
+     */
+    public SourceFile(int name_index, int length, int sourcefile_index, ConstantPool constant_pool) {
+        super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool);
+        this.sourcefile_index = sourcefile_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitSourceFile(this);
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(sourcefile_index);
+    }
+
+
+    /**
+     * @return Index in constant pool of source file name.
+     */
+    public final int getSourceFileIndex() {
+        return sourcefile_index;
+    }
+
+
+    /**
+     * @param sourcefile_index
+     */
+    public final void setSourceFileIndex( int sourcefile_index ) {
+        this.sourcefile_index = sourcefile_index;
+    }
+
+
+    /**
+     * @return Source file name.
+     */
+    public final String getSourceFileName() {
+        ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(sourcefile_index,
+                Constants.CONSTANT_Utf8);
+        return c.getBytes();
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return "SourceFile(" + getSourceFileName() + ")";
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        return (SourceFile) clone();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/StackMap.java b/java/org/apache/tomcat/util/bcel/classfile/StackMap.java
new file mode 100644 (file)
index 0000000..75b2e61
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a stack map attribute used for
+ * preverification of Java classes for the <a
+ * href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
+ * (J2ME). This attribute is used by the <a
+ * href="http://java.sun.com/products/cldc/">KVM</a> and contained
+ * within the Code attribute of a method. See CLDC specification
+ * ï¿½5.3.1.2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ * @see     StackMapEntry
+ * @see     StackMapType
+ */
+public final class StackMap extends Attribute implements Node {
+
+    private int map_length;
+    private StackMapEntry[] map; // Table of stack map entries
+
+
+    /*
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param map Table of stack map entries
+     * @param constant_pool Array of constants
+     */
+    public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) {
+        super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool);
+        setStackMap(map);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (StackMapEntry[]) null, constant_pool);
+        map_length = file.readUnsignedShort();
+        map = new StackMapEntry[map_length];
+        for (int i = 0; i < map_length; i++) {
+            map[i] = new StackMapEntry(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * Dump line number table attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(map_length);
+        for (int i = 0; i < map_length; i++) {
+            map[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Array of stack map entries
+     */
+    public final StackMapEntry[] getStackMap() {
+        return map;
+    }
+
+
+    /**
+     * @param map Array of stack map entries
+     */
+    public final void setStackMap( StackMapEntry[] map ) {
+        this.map = map;
+        map_length = (map == null) ? 0 : map.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer("StackMap(");
+        for (int i = 0; i < map_length; i++) {
+            buf.append(map[i].toString());
+            if (i < map_length - 1) {
+                buf.append(", ");
+            }
+        }
+        buf.append(')');
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        StackMap c = (StackMap) clone();
+        c.map = new StackMapEntry[map_length];
+        for (int i = 0; i < map_length; i++) {
+            c.map[i] = map[i].copy();
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackMap(this);
+    }
+
+
+    public final int getMapLength() {
+        return map_length;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/StackMapEntry.java b/java/org/apache/tomcat/util/bcel/classfile/StackMapEntry.java
new file mode 100644 (file)
index 0000000..f2df59a
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * This class represents a stack map entry recording the types of
+ * local variables and the the of stack items at a given byte code offset.
+ * See CLDC specification ï¿½5.3.1.2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     StackMap
+ * @see     StackMapType
+ */
+public final class StackMapEntry implements Cloneable {
+
+    private int byte_code_offset;
+    private int number_of_locals;
+    private StackMapType[] types_of_locals;
+    private int number_of_stack_items;
+    private StackMapType[] types_of_stack_items;
+    private ConstantPool constant_pool;
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException {
+        this(file.readShort(), file.readShort(), null, -1, null, constant_pool);
+        types_of_locals = new StackMapType[number_of_locals];
+        for (int i = 0; i < number_of_locals; i++) {
+            types_of_locals[i] = new StackMapType(file, constant_pool);
+        }
+        number_of_stack_items = file.readShort();
+        types_of_stack_items = new StackMapType[number_of_stack_items];
+        for (int i = 0; i < number_of_stack_items; i++) {
+            types_of_stack_items[i] = new StackMapType(file, constant_pool);
+        }
+    }
+
+
+    public StackMapEntry(int byte_code_offset, int number_of_locals,
+            StackMapType[] types_of_locals, int number_of_stack_items,
+            StackMapType[] types_of_stack_items, ConstantPool constant_pool) {
+        this.byte_code_offset = byte_code_offset;
+        this.number_of_locals = number_of_locals;
+        this.types_of_locals = types_of_locals;
+        this.number_of_stack_items = number_of_stack_items;
+        this.types_of_stack_items = types_of_stack_items;
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * Dump stack map entry
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeShort(byte_code_offset);
+        file.writeShort(number_of_locals);
+        for (int i = 0; i < number_of_locals; i++) {
+            types_of_locals[i].dump(file);
+        }
+        file.writeShort(number_of_stack_items);
+        for (int i = 0; i < number_of_stack_items; i++) {
+            types_of_stack_items[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer(64);
+        buf.append("(offset=").append(byte_code_offset);
+        if (number_of_locals > 0) {
+            buf.append(", locals={");
+            for (int i = 0; i < number_of_locals; i++) {
+                buf.append(types_of_locals[i]);
+                if (i < number_of_locals - 1) {
+                    buf.append(", ");
+                }
+            }
+            buf.append("}");
+        }
+        if (number_of_stack_items > 0) {
+            buf.append(", stack items={");
+            for (int i = 0; i < number_of_stack_items; i++) {
+                buf.append(types_of_stack_items[i]);
+                if (i < number_of_stack_items - 1) {
+                    buf.append(", ");
+                }
+            }
+            buf.append("}");
+        }
+        buf.append(")");
+        return buf.toString();
+    }
+
+
+    public void setByteCodeOffset( int b ) {
+        byte_code_offset = b;
+    }
+
+
+    public int getByteCodeOffset() {
+        return byte_code_offset;
+    }
+
+
+    public void setNumberOfLocals( int n ) {
+        number_of_locals = n;
+    }
+
+
+    public int getNumberOfLocals() {
+        return number_of_locals;
+    }
+
+
+    public void setTypesOfLocals( StackMapType[] t ) {
+        types_of_locals = t;
+    }
+
+
+    public StackMapType[] getTypesOfLocals() {
+        return types_of_locals;
+    }
+
+
+    public void setNumberOfStackItems( int n ) {
+        number_of_stack_items = n;
+    }
+
+
+    public int getNumberOfStackItems() {
+        return number_of_stack_items;
+    }
+
+
+    public void setTypesOfStackItems( StackMapType[] t ) {
+        types_of_stack_items = t;
+    }
+
+
+    public StackMapType[] getTypesOfStackItems() {
+        return types_of_stack_items;
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public StackMapEntry copy() {
+        try {
+            return (StackMapEntry) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackMapEntry(this);
+    }
+
+
+    /**
+     * @return Constant pool used by this object.
+     */
+    public final ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @param constant_pool Constant pool to be used for this object.
+     */
+    public final void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/StackMapTable.java b/java/org/apache/tomcat/util/bcel/classfile/StackMapTable.java
new file mode 100644 (file)
index 0000000..63d2477
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a stack map attribute used for
+ * preverification of Java classes for the <a
+ * href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
+ * (J2ME). This attribute is used by the <a
+ * href="http://java.sun.com/products/cldc/">KVM</a> and contained
+ * within the Code attribute of a method. See CLDC specification
+ * ï¿½ï¿½?5.3.1.2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Code
+ * @see     StackMapEntry
+ * @see     StackMapType
+ */
+public final class StackMapTable extends Attribute implements Node {
+
+    private int map_length;
+    private StackMapTableEntry[] map; // Table of stack map entries
+
+
+    /*
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param map Table of stack map entries
+     * @param constant_pool Array of constants
+     */
+    public StackMapTable(int name_index, int length, StackMapTableEntry[] map, ConstantPool constant_pool) {
+        super(Constants.ATTR_STACK_MAP_TABLE, name_index, length, constant_pool);
+        setStackMapTable(map);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index of name
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    StackMapTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (StackMapTableEntry[]) null, constant_pool);
+        map_length = file.readUnsignedShort();
+        map = new StackMapTableEntry[map_length];
+        for (int i = 0; i < map_length; i++) {
+            map[i] = new StackMapTableEntry(file, constant_pool);
+        }
+    }
+
+
+    /**
+     * Dump line number table attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        file.writeShort(map_length);
+        for (int i = 0; i < map_length; i++) {
+            map[i].dump(file);
+        }
+    }
+
+
+    /**
+     * @return Array of stack map entries
+     */
+    public final StackMapTableEntry[] getStackMapTable() {
+        return map;
+    }
+
+
+    /**
+     * @param map Array of stack map entries
+     */
+    public final void setStackMapTable( StackMapTableEntry[] map ) {
+        this.map = map;
+        map_length = (map == null) ? 0 : map.length;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer("StackMapTable(");
+        for (int i = 0; i < map_length; i++) {
+            buf.append(map[i].toString());
+            if (i < map_length - 1) {
+                buf.append(", ");
+            }
+        }
+        buf.append(')');
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        StackMapTable c = (StackMapTable) clone();
+        c.map = new StackMapTableEntry[map_length];
+        for (int i = 0; i < map_length; i++) {
+            c.map[i] = map[i].copy();
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackMapTable(this);
+    }
+
+
+    public final int getMapLength() {
+        return map_length;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/StackMapTableEntry.java b/java/org/apache/tomcat/util/bcel/classfile/StackMapTableEntry.java
new file mode 100644 (file)
index 0000000..4fd2708
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a stack map entry recording the types of
+ * local variables and the the of stack items at a given byte code offset.
+ * See CLDC specification ï¿½ï¿½?5.3.1.2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     StackMap
+ * @see     StackMapType
+ */
+public final class StackMapTableEntry implements Cloneable {
+
+       private int frame_type;
+    private int byte_code_offset_delta;
+    private int number_of_locals;
+    private StackMapType[] types_of_locals;
+    private int number_of_stack_items;
+    private StackMapType[] types_of_stack_items;
+    private ConstantPool constant_pool;
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    StackMapTableEntry(DataInputStream file, ConstantPool constant_pool) throws IOException {
+        this(file.read(), -1, -1, null, -1, null, constant_pool);
+        
+        if (frame_type >= Constants.SAME_FRAME && frame_type <= Constants.SAME_FRAME_MAX) {
+               byte_code_offset_delta = frame_type - Constants.SAME_FRAME;
+        } else if (frame_type >= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) {
+               byte_code_offset_delta = frame_type - Constants.SAME_LOCALS_1_STACK_ITEM_FRAME;
+               number_of_stack_items = 1;
+               types_of_stack_items = new StackMapType[1];
+               types_of_stack_items[0] = new StackMapType(file, constant_pool);
+        } else if (frame_type == Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+               byte_code_offset_delta = file.readShort();
+               number_of_stack_items = 1;
+               types_of_stack_items = new StackMapType[1];
+               types_of_stack_items[0] = new StackMapType(file, constant_pool);
+        } else if (frame_type >= Constants.CHOP_FRAME && frame_type <= Constants.CHOP_FRAME_MAX) {
+               byte_code_offset_delta = file.readShort();
+        } else if (frame_type == Constants.SAME_FRAME_EXTENDED) {
+               byte_code_offset_delta = file.readShort();
+        } else if (frame_type >= Constants.APPEND_FRAME && frame_type <= Constants.APPEND_FRAME_MAX) {
+               byte_code_offset_delta = file.readShort();
+               number_of_locals = frame_type - 251;
+               types_of_locals = new StackMapType[number_of_locals];
+               for (int i = 0; i < number_of_locals; i++) {
+                       types_of_locals[i] = new StackMapType(file, constant_pool);
+               }               
+        } else if (frame_type == Constants.FULL_FRAME) {        
+               byte_code_offset_delta = file.readShort();
+               number_of_locals = file.readShort();
+               types_of_locals = new StackMapType[number_of_locals];
+               for (int i = 0; i < number_of_locals; i++) {
+                       types_of_locals[i] = new StackMapType(file, constant_pool);
+               }
+               number_of_stack_items = file.readShort();
+               types_of_stack_items = new StackMapType[number_of_stack_items];
+               for (int i = 0; i < number_of_stack_items; i++) {
+                       types_of_stack_items[i] = new StackMapType(file, constant_pool);
+               }
+        } else {
+               /* Can't happen */
+               throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frame_type);
+        }
+    }
+
+
+    public StackMapTableEntry(int tag, int byte_code_offset_delta, int number_of_locals,
+            StackMapType[] types_of_locals, int number_of_stack_items,
+            StackMapType[] types_of_stack_items, ConstantPool constant_pool) {
+       this.frame_type = tag;
+        this.byte_code_offset_delta = byte_code_offset_delta;
+        this.number_of_locals = number_of_locals;
+        this.types_of_locals = types_of_locals;
+        this.number_of_stack_items = number_of_stack_items;
+        this.types_of_stack_items = types_of_stack_items;
+        this.constant_pool = constant_pool;
+    }
+
+
+    /**
+     * Dump stack map entry
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+       file.write(frame_type);
+       if (frame_type >= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) {
+               types_of_stack_items[0].dump(file);
+        } else if (frame_type == Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+               file.write(byte_code_offset_delta);
+               types_of_stack_items[0].dump(file);
+        } else if (frame_type >= Constants.CHOP_FRAME && frame_type <= Constants.CHOP_FRAME_MAX) {
+               file.write(byte_code_offset_delta);
+        } else if (frame_type == Constants.SAME_FRAME_EXTENDED) {
+               file.write(byte_code_offset_delta);
+        } else if (frame_type >= Constants.APPEND_FRAME && frame_type <= Constants.APPEND_FRAME_MAX) {
+               file.write(byte_code_offset_delta);
+               for (int i = 0; i < number_of_locals; i++) {
+                       types_of_locals[i].dump(file);
+               }               
+        } else if (frame_type == Constants.FULL_FRAME) {        
+            file.writeShort(byte_code_offset_delta);
+            file.writeShort(number_of_locals);
+            for (int i = 0; i < number_of_locals; i++) {
+                types_of_locals[i].dump(file);
+            }
+            file.writeShort(number_of_stack_items);
+            for (int i = 0; i < number_of_stack_items; i++) {
+                types_of_stack_items[i].dump(file);
+            }
+        } else {
+               /* Can't happen */
+               throw new ClassFormatException ("Invalid Stack map table tag: " + frame_type);
+        }
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer(64);
+        buf.append("(");
+        if (frame_type >= Constants.SAME_FRAME && frame_type <= Constants.SAME_FRAME_MAX) {
+               buf.append("SAME");
+        } else if (frame_type >= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) {
+               buf.append("SAME_LOCALS_1_STACK");
+        } else if (frame_type == Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+               buf.append("SAME_LOCALS_1_STACK_EXTENDED");
+        } else if (frame_type >= Constants.CHOP_FRAME && frame_type <= Constants.CHOP_FRAME_MAX) {
+               buf.append("CHOP "+(251-frame_type));
+        } else if (frame_type == Constants.SAME_FRAME_EXTENDED) {
+               buf.append("SAME_EXTENDED");
+        } else if (frame_type >= Constants.APPEND_FRAME && frame_type <= Constants.APPEND_FRAME_MAX) {
+               buf.append("APPEND "+(frame_type-251));
+        } else if (frame_type == Constants.FULL_FRAME) {        
+               buf.append("FULL");
+        } else {
+               buf.append("UNKNOWN");
+        }
+        buf.append(", offset delta=").append(byte_code_offset_delta);
+        if (number_of_locals > 0) {
+            buf.append(", locals={");
+            for (int i = 0; i < number_of_locals; i++) {
+                buf.append(types_of_locals[i]);
+                if (i < number_of_locals - 1) {
+                    buf.append(", ");
+                }
+            }
+            buf.append("}");
+        }
+        if (number_of_stack_items > 0) {
+            buf.append(", stack items={");
+            for (int i = 0; i < number_of_stack_items; i++) {
+                buf.append(types_of_stack_items[i]);
+                if (i < number_of_stack_items - 1) {
+                    buf.append(", ");
+                }
+            }
+            buf.append("}");
+        }
+        buf.append(")");
+        return buf.toString();
+    }
+
+
+    public void setByteCodeOffsetDelta( int b ) {
+        byte_code_offset_delta = b;
+    }
+
+
+    public int getByteCodeOffsetDelta() {
+        return byte_code_offset_delta;
+    }
+
+
+    public void setNumberOfLocals( int n ) {
+        number_of_locals = n;
+    }
+
+
+    public int getNumberOfLocals() {
+        return number_of_locals;
+    }
+
+
+    public void setTypesOfLocals( StackMapType[] t ) {
+        types_of_locals = t;
+    }
+
+
+    public StackMapType[] getTypesOfLocals() {
+        return types_of_locals;
+    }
+
+
+    public void setNumberOfStackItems( int n ) {
+        number_of_stack_items = n;
+    }
+
+
+    public int getNumberOfStackItems() {
+        return number_of_stack_items;
+    }
+
+
+    public void setTypesOfStackItems( StackMapType[] t ) {
+        types_of_stack_items = t;
+    }
+
+
+    public StackMapType[] getTypesOfStackItems() {
+        return types_of_stack_items;
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public StackMapTableEntry copy() {
+        try {
+            return (StackMapTableEntry) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackMapTableEntry(this);
+    }
+
+
+    /**
+     * @return Constant pool used by this object.
+     */
+    public final ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @param constant_pool Constant pool to be used for this object.
+     */
+    public final void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/StackMapType.java b/java/org/apache/tomcat/util/bcel/classfile/StackMapType.java
new file mode 100644 (file)
index 0000000..b923671
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents the type of a local variable or item on stack
+ * used in the StackMap entries.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     StackMapEntry
+ * @see     StackMap
+ * @see     Constants
+ */
+public final class StackMapType implements Cloneable {
+
+    private byte type;
+    private int index = -1; // Index to CONSTANT_Class or offset
+    private ConstantPool constant_pool;
+
+
+    /**
+     * Construct object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     */
+    StackMapType(DataInput file, ConstantPool constant_pool) throws IOException {
+        this(file.readByte(), -1, constant_pool);
+        if (hasIndex()) {
+            setIndex(file.readShort());
+        }
+        setConstantPool(constant_pool);
+    }
+
+
+    /**
+     * @param type type tag as defined in the Constants interface
+     * @param index index to constant pool, or byte code offset
+     */
+    public StackMapType(byte type, int index, ConstantPool constant_pool) {
+        setType(type);
+        setIndex(index);
+        setConstantPool(constant_pool);
+    }
+
+
+    public void setType( byte t ) {
+        if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) {
+            throw new RuntimeException("Illegal type for StackMapType: " + t);
+        }
+        type = t;
+    }
+
+
+    public byte getType() {
+        return type;
+    }
+
+
+    public void setIndex( int t ) {
+        index = t;
+    }
+
+
+    /** @return index to constant pool if type == ITEM_Object, or offset
+     * in byte code, if type == ITEM_NewObject, and -1 otherwise
+     */
+    public int getIndex() {
+        return index;
+    }
+
+
+    /**
+     * Dump type entries to file.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        file.writeByte(type);
+        if (hasIndex()) {
+            file.writeShort(getIndex());
+        }
+    }
+
+
+    /** @return true, if type is either ITEM_Object or ITEM_NewObject
+     */
+    public final boolean hasIndex() {
+        return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject));
+    }
+
+
+    private String printIndex() {
+        if (type == Constants.ITEM_Object) {
+            if (index < 0) {
+                return ", class=<unknown>";
+            }
+            return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class);
+        } else if (type == Constants.ITEM_NewObject) {
+            return ", offset=" + index;
+        } else {
+            return "";
+        }
+    }
+
+
+    /**
+     * @return String representation
+     */
+    public final String toString() {
+        return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")";
+    }
+
+
+    /**
+     * @return deep copy of this object
+     */
+    public StackMapType copy() {
+        try {
+            return (StackMapType) clone();
+        } catch (CloneNotSupportedException e) {
+        }
+        return null;
+    }
+
+
+    /**
+     * @return Constant pool used by this object.
+     */
+    public final ConstantPool getConstantPool() {
+        return constant_pool;
+    }
+
+
+    /**
+     * @param constant_pool Constant pool to be used for this object.
+     */
+    public final void setConstantPool( ConstantPool constant_pool ) {
+        this.constant_pool = constant_pool;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Synthetic.java b/java/org/apache/tomcat/util/bcel/classfile/Synthetic.java
new file mode 100644 (file)
index 0000000..d0cade5
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class is derived from <em>Attribute</em> and declares this class as
+ * `synthetic', i.e., it needs special handling.  The JVM specification
+ * states "A class member that does not appear in the source code must be
+ * marked using a Synthetic attribute."  It may appear in the ClassFile
+ * attribute table, a field_info table or a method_info table.  This class
+ * is intended to be instantiated from the
+ * <em>Attribute.readAttribute()</em> method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Attribute
+ */
+public final class Synthetic extends Attribute {
+
+    private byte[] bytes;
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use copy() for a physical copy.
+     */
+    public Synthetic(Synthetic c) {
+        this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
+    }
+
+
+    /**
+     * @param name_index Index in constant pool to CONSTANT_Utf8, which
+     * should represent the string "Synthetic".
+     * @param length Content length in bytes - should be zero.
+     * @param bytes Attribute contents
+     * @param constant_pool The constant pool this attribute is associated
+     * with.
+     */
+    public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) {
+        super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool);
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool to CONSTANT_Utf8
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (byte[]) null, constant_pool);
+        if (length > 0) {
+            bytes = new byte[length];
+            file.readFully(bytes);
+            System.err.println("Synthetic attribute with length > 0");
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitSynthetic(this);
+    }
+
+
+    /**
+     * Dump source file attribute to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        if (length > 0) {
+            file.write(bytes, 0, length);
+        }
+    }
+
+
+    /**
+     * @return data bytes.
+     */
+    public final byte[] getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @param bytes
+     */
+    public final void setBytes( byte[] bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        StringBuffer buf = new StringBuffer("Synthetic");
+        if (length > 0) {
+            buf.append(" ").append(Utility.toHexString(bytes));
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        Synthetic c = (Synthetic) clone();
+        if (bytes != null) {
+            c.bytes = new byte[bytes.length];
+            System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Unknown.java b/java/org/apache/tomcat/util/bcel/classfile/Unknown.java
new file mode 100644 (file)
index 0000000..b699963
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * This class represents a reference to an unknown (i.e.,
+ * application-specific) attribute of a class.  It is instantiated from the
+ * <em>Attribute.readAttribute()</em> method.  Applications that need to
+ * read in application-specific attributes should create an <a
+ * href="./AttributeReader.html">AttributeReader</a> implementation and
+ * attach it via <a
+ * href="./Attribute.html#addAttributeReader(java.lang.String,
+ * org.apache.tomcat.util.bcel.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
+
+ *
+ * @version $Id$
+ * @see org.apache.tomcat.util.bcel.classfile.Attribute
+ * @see org.apache.tomcat.util.bcel.classfile.AttributeReader
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class Unknown extends Attribute {
+
+    private byte[] bytes;
+    private String name;
+    private static Map unknown_attributes = new HashMap();
+
+
+    /** @return array of unknown attributes, but just one for each kind.
+     */
+    static Unknown[] getUnknownAttributes() {
+        Unknown[] unknowns = new Unknown[unknown_attributes.size()];
+        Iterator entries = unknown_attributes.values().iterator();
+        for (int i = 0; entries.hasNext(); i++) {
+            unknowns[i] = (Unknown) entries.next();
+        }
+        unknown_attributes.clear();
+        return unknowns;
+    }
+
+
+    /**
+     * Initialize from another object. Note that both objects use the same
+     * references (shallow copy). Use clone() for a physical copy.
+     */
+    public Unknown(Unknown c) {
+        this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
+    }
+
+
+    /**
+     * Create a non-standard attribute.
+     *
+     * @param name_index Index in constant pool
+     * @param length Content length in bytes
+     * @param bytes Attribute contents
+     * @param constant_pool Array of constants
+     */
+    public Unknown(int name_index, int length, byte[] bytes, ConstantPool constant_pool) {
+        super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool);
+        this.bytes = bytes;
+        name = ((ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8))
+                .getBytes();
+        unknown_attributes.put(name, this);
+    }
+
+
+    /**
+     * Construct object from file stream.
+     * @param name_index Index in constant pool
+     * @param length Content length in bytes
+     * @param file Input stream
+     * @param constant_pool Array of constants
+     * @throws IOException
+     */
+    Unknown(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
+            throws IOException {
+        this(name_index, length, (byte[]) null, constant_pool);
+        if (length > 0) {
+            bytes = new byte[length];
+            file.readFully(bytes);
+        }
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitUnknown(this);
+    }
+
+
+    /**
+     * Dump unknown bytes to file stream.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    public final void dump( DataOutputStream file ) throws IOException {
+        super.dump(file);
+        if (length > 0) {
+            file.write(bytes, 0, length);
+        }
+    }
+
+
+    /**
+     * @return data bytes.
+     */
+    public final byte[] getBytes() {
+        return bytes;
+    }
+
+
+    /**
+     * @return name of attribute.
+     */
+    public final String getName() {
+        return name;
+    }
+
+
+    /**
+     * @param bytes the bytes to set
+     */
+    public final void setBytes( byte[] bytes ) {
+        this.bytes = bytes;
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public final String toString() {
+        if (length == 0 || bytes == null) {
+            return "(Unknown attribute " + name + ")";
+        }
+        String hex;
+        if (length > 10) {
+            byte[] tmp = new byte[10];
+            System.arraycopy(bytes, 0, tmp, 0, 10);
+            hex = Utility.toHexString(tmp) + "... (truncated)";
+        } else {
+            hex = Utility.toHexString(bytes);
+        }
+        return "(Unknown attribute " + name + ": " + hex + ")";
+    }
+
+
+    /**
+     * @return deep copy of this attribute
+     */
+    public Attribute copy( ConstantPool _constant_pool ) {
+        Unknown c = (Unknown) clone();
+        if (bytes != null) {
+            c.bytes = new byte[bytes.length];
+            System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
+        }
+        c.constant_pool = _constant_pool;
+        return c;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Utility.java b/java/org/apache/tomcat/util/bcel/classfile/Utility.java
new file mode 100644 (file)
index 0000000..73ca68b
--- /dev/null
@@ -0,0 +1,1525 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.CharArrayWriter;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FilterReader;
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.generic.AnnotationEntryGen;
+import org.apache.tomcat.util.bcel.generic.ConstantPoolGen;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/**
+ * Utility functions that do not really belong to any class in particular.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class Utility {
+
+    private static int unwrap( ThreadLocal tl ) {
+        return ((Integer) tl.get()).intValue();
+    }
+
+
+    private static void wrap( ThreadLocal tl, int value ) {
+        tl.set(new Integer(value));
+    }
+
+    private static ThreadLocal consumed_chars = new ThreadLocal() {
+
+        protected Object initialValue() {
+            return new Integer(0);
+        }
+    };/* How many chars have been consumed
+     * during parsing in signatureToString().
+     * Read by methodSignatureToString().
+     * Set by side effect,but only internally.
+     */
+    private static boolean wide = false; /* The `WIDE' instruction is used in the
+     * byte code to allow 16-bit wide indices
+     * for local variables. This opcode
+     * precedes an `ILOAD', e.g.. The opcode
+     * immediately following takes an extra
+     * byte which is combined with the
+     * following byte to form a
+     * 16-bit value.
+     */
+
+
+    /**
+     * Convert bit field of flags into string such as `static final'.
+     *
+     * @param  access_flags Access flags
+     * @return String representation of flags
+     */
+    public static final String accessToString( int access_flags ) {
+        return accessToString(access_flags, false);
+    }
+
+
+    /**
+     * Convert bit field of flags into string such as `static final'.
+     *
+     * Special case: Classes compiled with new compilers and with the
+     * `ACC_SUPER' flag would be said to be "synchronized". This is
+     * because SUN used the same value for the flags `ACC_SUPER' and
+     * `ACC_SYNCHRONIZED'. 
+     *
+     * @param  access_flags Access flags
+     * @param  for_class access flags are for class qualifiers ?
+     * @return String representation of flags
+     */
+    public static final String accessToString( int access_flags, boolean for_class ) {
+        StringBuffer buf = new StringBuffer();
+        int p = 0;
+        for (int i = 0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags
+            p = pow2(i);
+            if ((access_flags & p) != 0) {
+                /* Special case: Classes compiled with new compilers and with the
+                 * `ACC_SUPER' flag would be said to be "synchronized". This is
+                 * because SUN used the same value for the flags `ACC_SUPER' and
+                 * `ACC_SYNCHRONIZED'.
+                 */
+                if (for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) {
+                    continue;
+                }
+                buf.append(Constants.ACCESS_NAMES[i]).append(" ");
+            }
+        }
+        return buf.toString().trim();
+    }
+
+
+    /**
+     * @return "class" or "interface", depending on the ACC_INTERFACE flag
+     */
+    public static final String classOrInterface( int access_flags ) {
+        return ((access_flags & Constants.ACC_INTERFACE) != 0) ? "interface" : "class";
+    }
+
+
+    /**
+     * Disassemble a byte array of JVM byte codes starting from code line 
+     * `index' and return the disassembled string representation. Decode only
+     * `num' opcodes (including their operands), use -1 if you want to
+     * decompile everything.
+     *
+     * @param  code byte code array
+     * @param  constant_pool Array of constants
+     * @param  index offset in `code' array
+     * <EM>(number of opcodes, not bytes!)</EM>
+     * @param  length number of opcodes to decompile, -1 for all
+     * @param  verbose be verbose, e.g. print constant pool index
+     * @return String representation of byte codes
+     */
+    public static final String codeToString( byte[] code, ConstantPool constant_pool, int index,
+            int length, boolean verbose ) {
+        StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient
+        ByteSequence stream = new ByteSequence(code);
+        try {
+            for (int i = 0; i < index; i++) {
+                codeToString(stream, constant_pool, verbose);
+            }
+            for (int i = 0; stream.available() > 0; i++) {
+                if ((length < 0) || (i < length)) {
+                    String indices = fillup(stream.getIndex() + ":", 6, true, ' ');
+                    buf.append(indices).append(codeToString(stream, constant_pool, verbose))
+                            .append('\n');
+                }
+            }
+        } catch (IOException e) {
+            System.out.println(buf.toString());
+            e.printStackTrace();
+            throw new ClassFormatException("Byte code error: " + e, e);
+        }
+        return buf.toString();
+    }
+
+
+    public static final String codeToString( byte[] code, ConstantPool constant_pool, int index,
+            int length ) {
+        return codeToString(code, constant_pool, index, length, true);
+    }
+
+
+    /**
+     * Disassemble a stream of byte codes and return the
+     * string representation.
+     *
+     * @param  bytes stream of bytes
+     * @param  constant_pool Array of constants
+     * @param  verbose be verbose, e.g. print constant pool index
+     * @return String representation of byte code
+     */
+    public static final String codeToString( ByteSequence bytes, ConstantPool constant_pool,
+            boolean verbose ) throws IOException {
+        short opcode = (short) bytes.readUnsignedByte();
+        int default_offset = 0, low, high, npairs;
+        int index, vindex, constant;
+        int[] match, jump_table;
+        int no_pad_bytes = 0, offset;
+        StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]);
+        /* Special case: Skip (0-3) padding bytes, i.e., the
+         * following bytes are 4-byte-aligned
+         */
+        if ((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) {
+            int remainder = bytes.getIndex() % 4;
+            no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
+            for (int i = 0; i < no_pad_bytes; i++) {
+                byte b;
+                if ((b = bytes.readByte()) != 0) {
+                    System.err.println("Warning: Padding byte != 0 in "
+                            + Constants.OPCODE_NAMES[opcode] + ":" + b);
+                }
+            }
+            // Both cases have a field default_offset in common
+            default_offset = bytes.readInt();
+        }
+        switch (opcode) {
+            /* Table switch has variable length arguments.
+             */
+            case Constants.TABLESWITCH:
+                low = bytes.readInt();
+                high = bytes.readInt();
+                offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
+                default_offset += offset;
+                buf.append("\tdefault = ").append(default_offset).append(", low = ").append(low)
+                        .append(", high = ").append(high).append("(");
+                jump_table = new int[high - low + 1];
+                for (int i = 0; i < jump_table.length; i++) {
+                    jump_table[i] = offset + bytes.readInt();
+                    buf.append(jump_table[i]);
+                    if (i < jump_table.length - 1) {
+                        buf.append(", ");
+                    }
+                }
+                buf.append(")");
+                break;
+            /* Lookup switch has variable length arguments.
+             */
+            case Constants.LOOKUPSWITCH: {
+                npairs = bytes.readInt();
+                offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
+                match = new int[npairs];
+                jump_table = new int[npairs];
+                default_offset += offset;
+                buf.append("\tdefault = ").append(default_offset).append(", npairs = ").append(
+                        npairs).append(" (");
+                for (int i = 0; i < npairs; i++) {
+                    match[i] = bytes.readInt();
+                    jump_table[i] = offset + bytes.readInt();
+                    buf.append("(").append(match[i]).append(", ").append(jump_table[i]).append(")");
+                    if (i < npairs - 1) {
+                        buf.append(", ");
+                    }
+                }
+                buf.append(")");
+            }
+                break;
+            /* Two address bytes + offset from start of byte stream form the
+             * jump target
+             */
+            case Constants.GOTO:
+            case Constants.IFEQ:
+            case Constants.IFGE:
+            case Constants.IFGT:
+            case Constants.IFLE:
+            case Constants.IFLT:
+            case Constants.JSR:
+            case Constants.IFNE:
+            case Constants.IFNONNULL:
+            case Constants.IFNULL:
+            case Constants.IF_ACMPEQ:
+            case Constants.IF_ACMPNE:
+            case Constants.IF_ICMPEQ:
+            case Constants.IF_ICMPGE:
+            case Constants.IF_ICMPGT:
+            case Constants.IF_ICMPLE:
+            case Constants.IF_ICMPLT:
+            case Constants.IF_ICMPNE:
+                buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readShort());
+                break;
+            /* 32-bit wide jumps
+             */
+            case Constants.GOTO_W:
+            case Constants.JSR_W:
+                buf.append("\t\t#").append(((bytes.getIndex() - 1) + bytes.readInt()));
+                break;
+            /* Index byte references local variable (register)
+             */
+            case Constants.ALOAD:
+            case Constants.ASTORE:
+            case Constants.DLOAD:
+            case Constants.DSTORE:
+            case Constants.FLOAD:
+            case Constants.FSTORE:
+            case Constants.ILOAD:
+            case Constants.ISTORE:
+            case Constants.LLOAD:
+            case Constants.LSTORE:
+            case Constants.RET:
+                if (wide) {
+                    vindex = bytes.readUnsignedShort();
+                    wide = false; // Clear flag
+                } else {
+                    vindex = bytes.readUnsignedByte();
+                }
+                buf.append("\t\t%").append(vindex);
+                break;
+            /*
+             * Remember wide byte which is used to form a 16-bit address in the
+             * following instruction. Relies on that the method is called again with
+             * the following opcode.
+             */
+            case Constants.WIDE:
+                wide = true;
+                buf.append("\t(wide)");
+                break;
+            /* Array of basic type.
+             */
+            case Constants.NEWARRAY:
+                buf.append("\t\t<").append(Constants.TYPE_NAMES[bytes.readByte()]).append(">");
+                break;
+            /* Access object/class fields.
+             */
+            case Constants.GETFIELD:
+            case Constants.GETSTATIC:
+            case Constants.PUTFIELD:
+            case Constants.PUTSTATIC:
+                index = bytes.readUnsignedShort();
+                buf.append("\t\t").append(
+                        constant_pool.constantToString(index, Constants.CONSTANT_Fieldref)).append(
+                        (verbose ? " (" + index + ")" : ""));
+                break;
+            /* Operands are references to classes in constant pool
+             */
+            case Constants.NEW:
+            case Constants.CHECKCAST:
+                buf.append("\t");
+                /* FALL THRU */
+            case Constants.INSTANCEOF:
+                index = bytes.readUnsignedShort();
+                buf.append("\t<").append(
+                        constant_pool.constantToString(index, Constants.CONSTANT_Class))
+                        .append(">").append((verbose ? " (" + index + ")" : ""));
+                break;
+            /* Operands are references to methods in constant pool
+             */
+            case Constants.INVOKESPECIAL:
+            case Constants.INVOKESTATIC:
+            case Constants.INVOKEVIRTUAL:
+                index = bytes.readUnsignedShort();
+                buf.append("\t").append(
+                        constant_pool.constantToString(index, Constants.CONSTANT_Methodref))
+                        .append((verbose ? " (" + index + ")" : ""));
+                break;
+            case Constants.INVOKEINTERFACE:
+                index = bytes.readUnsignedShort();
+                int nargs = bytes.readUnsignedByte(); // historical, redundant
+                buf.append("\t").append(
+                        constant_pool
+                                .constantToString(index, Constants.CONSTANT_InterfaceMethodref))
+                        .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t")
+                        .append(bytes.readUnsignedByte()); // Last byte is a reserved space
+                break;
+            /* Operands are references to items in constant pool
+             */
+            case Constants.LDC_W:
+            case Constants.LDC2_W:
+                index = bytes.readUnsignedShort();
+                buf.append("\t\t").append(
+                        constant_pool.constantToString(index, constant_pool.getConstant(index)
+                                .getTag())).append((verbose ? " (" + index + ")" : ""));
+                break;
+            case Constants.LDC:
+                index = bytes.readUnsignedByte();
+                buf.append("\t\t").append(
+                        constant_pool.constantToString(index, constant_pool.getConstant(index)
+                                .getTag())).append((verbose ? " (" + index + ")" : ""));
+                break;
+            /* Array of references.
+             */
+            case Constants.ANEWARRAY:
+                index = bytes.readUnsignedShort();
+                buf.append("\t\t<").append(
+                        compactClassName(constant_pool.getConstantString(index,
+                                Constants.CONSTANT_Class), false)).append(">").append(
+                        (verbose ? " (" + index + ")" : ""));
+                break;
+            /* Multidimensional array of references.
+             */
+            case Constants.MULTIANEWARRAY: {
+                index = bytes.readUnsignedShort();
+                int dimensions = bytes.readUnsignedByte();
+                buf.append("\t<").append(
+                        compactClassName(constant_pool.getConstantString(index,
+                                Constants.CONSTANT_Class), false)).append(">\t").append(dimensions)
+                        .append((verbose ? " (" + index + ")" : ""));
+            }
+                break;
+            /* Increment local variable.
+             */
+            case Constants.IINC:
+                if (wide) {
+                    vindex = bytes.readUnsignedShort();
+                    constant = bytes.readShort();
+                    wide = false;
+                } else {
+                    vindex = bytes.readUnsignedByte();
+                    constant = bytes.readByte();
+                }
+                buf.append("\t\t%").append(vindex).append("\t").append(constant);
+                break;
+            default:
+                if (Constants.NO_OF_OPERANDS[opcode] > 0) {
+                    for (int i = 0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) {
+                        buf.append("\t\t");
+                        switch (Constants.TYPE_OF_OPERANDS[opcode][i]) {
+                            case Constants.T_BYTE:
+                                buf.append(bytes.readByte());
+                                break;
+                            case Constants.T_SHORT:
+                                buf.append(bytes.readShort());
+                                break;
+                            case Constants.T_INT:
+                                buf.append(bytes.readInt());
+                                break;
+                            default: // Never reached
+                                System.err.println("Unreachable default case reached!");
+                                System.exit(-1);
+                        }
+                    }
+                }
+        }
+        return buf.toString();
+    }
+
+
+    public static final String codeToString( ByteSequence bytes, ConstantPool constant_pool )
+            throws IOException {
+        return codeToString(bytes, constant_pool, true);
+    }
+
+
+    /**
+     * Shorten long class names, <em>java/lang/String</em> becomes 
+     * <em>String</em>.
+     *
+     * @param str The long class name
+     * @return Compacted class name
+     */
+    public static final String compactClassName( String str ) {
+        return compactClassName(str, true);
+    }
+
+
+    /**
+     * Shorten long class name <em>str</em>, i.e., chop off the <em>prefix</em>,
+     * if the
+     * class name starts with this string and the flag <em>chopit</em> is true.
+     * Slashes <em>/</em> are converted to dots <em>.</em>.
+     *
+     * @param str The long class name
+     * @param prefix The prefix the get rid off
+     * @param chopit Flag that determines whether chopping is executed or not
+     * @return Compacted class name
+     */
+    public static final String compactClassName( String str, String prefix, boolean chopit ) {
+        int len = prefix.length();
+        str = str.replace('/', '.'); // Is `/' on all systems, even DOS
+        if (chopit) {
+            // If string starts with `prefix' and contains no further dots
+            if (str.startsWith(prefix) && (str.substring(len).indexOf('.') == -1)) {
+                str = str.substring(len);
+            }
+        }
+        return str;
+    }
+
+
+    /**
+     * Shorten long class names, <em>java/lang/String</em> becomes 
+     * <em>java.lang.String</em>,
+     * e.g.. If <em>chopit</em> is <em>true</em> the prefix <em>java.lang</em>
+     * is also removed.
+     *
+     * @param str The long class name
+     * @param chopit Flag that determines whether chopping is executed or not
+     * @return Compacted class name
+     */
+    public static final String compactClassName( String str, boolean chopit ) {
+        return compactClassName(str, "java.lang.", chopit);
+    }
+
+
+    /**
+     * @return `flag' with bit `i' set to 1
+     */
+    public static final int setBit( int flag, int i ) {
+        return flag | pow2(i);
+    }
+
+
+    /**
+     * @return `flag' with bit `i' set to 0
+     */
+    public static final int clearBit( int flag, int i ) {
+        int bit = pow2(i);
+        return (flag & bit) == 0 ? flag : flag ^ bit;
+    }
+
+
+    /**
+     * @return true, if bit `i' in `flag' is set
+     */
+    public static final boolean isSet( int flag, int i ) {
+        return (flag & pow2(i)) != 0;
+    }
+
+
+    /**
+     * Converts string containing the method return and argument types 
+     * to a byte code method signature.
+     *
+     * @param  ret Return type of method
+     * @param  argv Types of method arguments
+     * @return Byte code representation of method signature
+     */
+    public final static String methodTypeToSignature( String ret, String[] argv )
+            throws ClassFormatException {
+        StringBuffer buf = new StringBuffer("(");
+        String str;
+        if (argv != null) {
+            for (int i = 0; i < argv.length; i++) {
+                str = getSignature(argv[i]);
+                if (str.endsWith("V")) {
+                    throw new ClassFormatException("Invalid type: " + argv[i]);
+                }
+                buf.append(str);
+            }
+        }
+        str = getSignature(ret);
+        buf.append(")").append(str);
+        return buf.toString();
+    }
+
+
+    /**
+     * @param  signature    Method signature
+     * @return Array of argument types
+     * @throws  ClassFormatException  
+     */
+    public static final String[] methodSignatureArgumentTypes( String signature )
+            throws ClassFormatException {
+        return methodSignatureArgumentTypes(signature, true);
+    }
+
+
+    /**
+     * @param  signature    Method signature
+     * @param chopit Shorten class names ?
+     * @return Array of argument types
+     * @throws  ClassFormatException  
+     */
+    public static final String[] methodSignatureArgumentTypes( String signature, boolean chopit )
+            throws ClassFormatException {
+        List vec = new ArrayList();
+        int index;
+        try { // Read all declarations between for `(' and `)'
+            if (signature.charAt(0) != '(') {
+                throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+            index = 1; // current string position
+            while (signature.charAt(index) != ')') {
+                vec.add(signatureToString(signature.substring(index), chopit));
+                //corrected concurrent private static field acess
+                index += unwrap(consumed_chars); // update position
+            }
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+        return (String[]) vec.toArray(new String[vec.size()]);
+    }
+
+
+    /**
+     * @param  signature    Method signature
+     * @return return type of method
+     * @throws  ClassFormatException  
+     */
+    public static final String methodSignatureReturnType( String signature )
+            throws ClassFormatException {
+        return methodSignatureReturnType(signature, true);
+    }
+
+
+    /**
+     * @param  signature    Method signature
+     * @param chopit Shorten class names ?
+     * @return return type of method
+     * @throws  ClassFormatException  
+     */
+    public static final String methodSignatureReturnType( String signature, boolean chopit )
+            throws ClassFormatException {
+        int index;
+        String type;
+        try {
+            // Read return type after `)'
+            index = signature.lastIndexOf(')') + 1;
+            type = signatureToString(signature.substring(index), chopit);
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+        return type;
+    }
+
+
+    /**
+     * Converts method signature to string with all class names compacted.
+     *
+     * @param signature to convert
+     * @param name of method
+     * @param access flags of method
+     * @return Human readable signature
+     */
+    public static final String methodSignatureToString( String signature, String name, String access ) {
+        return methodSignatureToString(signature, name, access, true);
+    }
+
+
+    public static final String methodSignatureToString( String signature, String name,
+            String access, boolean chopit ) {
+        return methodSignatureToString(signature, name, access, chopit, null);
+    }
+
+
+    /**
+     * A returntype signature represents the return value from a method.
+     * It is a series of bytes in the following grammar:
+     *
+     * <return_signature> ::= <field_type> | V
+     *
+     * The character V indicates that the method returns no value. Otherwise, the
+     * signature indicates the type of the return value.
+     * An argument signature represents an argument passed to a method:
+     *
+     * <argument_signature> ::= <field_type>
+     *
+     * A method signature represents the arguments that the method expects, and
+     * the value that it returns.
+     * <method_signature> ::= (<arguments_signature>) <return_signature>
+     * <arguments_signature>::= <argument_signature>*
+     *
+     * This method converts such a string into a Java type declaration like
+     * `void main(String[])' and throws a `ClassFormatException' when the parsed 
+     * type is invalid.
+     *
+     * @param  signature    Method signature
+     * @param  name         Method name
+     * @param  access       Method access rights
+     * @return Java type declaration
+     * @throws  ClassFormatException  
+     */
+    public static final String methodSignatureToString( String signature, String name,
+            String access, boolean chopit, LocalVariableTable vars ) throws ClassFormatException {
+        StringBuffer buf = new StringBuffer("(");
+        String type;
+        int index;
+        int var_index = (access.indexOf("static") >= 0) ? 0 : 1;
+        try { // Read all declarations between for `(' and `)'
+            if (signature.charAt(0) != '(') {
+                throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+            index = 1; // current string position
+            while (signature.charAt(index) != ')') {
+                String param_type = signatureToString(signature.substring(index), chopit);
+                buf.append(param_type);
+                if (vars != null) {
+                    LocalVariable l = vars.getLocalVariable(var_index);
+                    if (l != null) {
+                        buf.append(" ").append(l.getName());
+                    }
+                } else {
+                    buf.append(" arg").append(var_index);
+                }
+                if ("double".equals(param_type) || "long".equals(param_type)) {
+                    var_index += 2;
+                } else {
+                    var_index++;
+                }
+                buf.append(", ");
+                //corrected concurrent private static field acess
+                index += unwrap(consumed_chars); // update position
+            }
+            index++; // update position
+            // Read return type after `)'
+            type = signatureToString(signature.substring(index), chopit);
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+        if (buf.length() > 1) {
+            buf.setLength(buf.length() - 2);
+        }
+        buf.append(")");
+        return access + ((access.length() > 0) ? " " : "") + // May be an empty string
+                type + " " + name + buf.toString();
+    }
+
+
+    // Guess what this does
+    private static final int pow2( int n ) {
+        return 1 << n;
+    }
+
+
+    /**
+     * Replace all occurrences of <em>old</em> in <em>str</em> with <em>new</em>.
+     *
+     * @param str String to permute
+     * @param old String to be replaced
+     * @param new_ Replacement string
+     * @return new String object
+     */
+    public static final String replace( String str, String old, String new_ ) {
+        int index, old_index;
+        try {
+            if ((index = str.indexOf(old)) != -1) { // `old' found in str
+                StringBuffer buf = new StringBuffer();
+                old_index = 0; // String start offset
+                // While we have something to replace
+                while ((index = str.indexOf(old, old_index)) != -1) {
+                    buf.append(str.substring(old_index, index)); // append prefix
+                    buf.append(new_); // append replacement
+                    old_index = index + old.length(); // Skip `old'.length chars
+                }
+                buf.append(str.substring(old_index)); // append rest of string
+                str = buf.toString();
+            }
+        } catch (StringIndexOutOfBoundsException e) { // Should not occur
+            System.err.println(e);
+        }
+        return str;
+    }
+
+
+    /**
+     * Converts signature to string with all class names compacted.
+     *
+     * @param signature to convert
+     * @return Human readable signature
+     */
+    public static final String signatureToString( String signature ) {
+        return signatureToString(signature, true);
+    }
+
+
+    /**
+     * The field signature represents the value of an argument to a function or 
+     * the value of a variable. It is a series of bytes generated by the 
+     * following grammar:
+     *
+     * <PRE>
+     * <field_signature> ::= <field_type>
+     * <field_type>      ::= <base_type>|<object_type>|<array_type>
+     * <base_type>       ::= B|C|D|F|I|J|S|Z
+     * <object_type>     ::= L<fullclassname>;
+     * <array_type>      ::= [<field_type>
+     *
+     * The meaning of the base types is as follows:
+     * B byte signed byte
+     * C char character
+     * D double double precision IEEE float
+     * F float single precision IEEE float
+     * I int integer
+     * J long long integer
+     * L<fullclassname>; ... an object of the given class
+     * S short signed short
+     * Z boolean true or false
+     * [<field sig> ... array
+     * </PRE>
+     *
+     * This method converts this string into a Java type declaration such as
+     * `String[]' and throws a `ClassFormatException' when the parsed type is 
+     * invalid.
+     *
+     * @param  signature  Class signature
+     * @param chopit Flag that determines whether chopping is executed or not
+     * @return Java type declaration
+     * @throws ClassFormatException
+     */
+    public static final String signatureToString( String signature, boolean chopit ) {
+        //corrected concurrent private static field acess
+        wrap(consumed_chars, 1); // This is the default, read just one char like `B'
+        try {
+            switch (signature.charAt(0)) {
+                case 'B':
+                    return "byte";
+                case 'C':
+                    return "char";
+                case 'D':
+                    return "double";
+                case 'F':
+                    return "float";
+                case 'I':
+                    return "int";
+                case 'J':
+                    return "long";
+                case 'L': { // Full class name
+                    int index = signature.indexOf(';'); // Look for closing `;'
+                    if (index < 0) {
+                        throw new ClassFormatException("Invalid signature: " + signature);
+                    }
+                    //corrected concurrent private static field acess
+                    wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed
+                    return compactClassName(signature.substring(1, index), chopit);
+                }
+                case 'S':
+                    return "short";
+                case 'Z':
+                    return "boolean";
+                case '[': { // Array declaration
+                    int n;
+                    StringBuffer brackets;
+                    String type;
+                    int consumed_chars; // Shadows global var
+                    brackets = new StringBuffer(); // Accumulate []'s
+                    // Count opening brackets and look for optional size argument
+                    for (n = 0; signature.charAt(n) == '['; n++) {
+                        brackets.append("[]");
+                    }
+                    consumed_chars = n; // Remember value
+                    // The rest of the string denotes a `<field_type>'
+                    type = signatureToString(signature.substring(n), chopit);
+                    //corrected concurrent private static field acess
+                    //Utility.consumed_chars += consumed_chars; is replaced by:
+                    int _temp = unwrap(Utility.consumed_chars) + consumed_chars;
+                    wrap(Utility.consumed_chars, _temp);
+                    return type + brackets.toString();
+                }
+                case 'V':
+                    return "void";
+                default:
+                    throw new ClassFormatException("Invalid signature: `" + signature + "'");
+            }
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid signature: " + signature, e);
+        }
+    }
+
+
+    /** Parse Java type such as "char", or "java.lang.String[]" and return the
+     * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively.
+     *
+     * @param  type Java type
+     * @return byte code signature
+     */
+    public static String getSignature( String type ) {
+        StringBuffer buf = new StringBuffer();
+        char[] chars = type.toCharArray();
+        boolean char_found = false, delim = false;
+        int index = -1;
+        loop: for (int i = 0; i < chars.length; i++) {
+            switch (chars[i]) {
+                case ' ':
+                case '\t':
+                case '\n':
+                case '\r':
+                case '\f':
+                    if (char_found) {
+                        delim = true;
+                    }
+                    break;
+                case '[':
+                    if (!char_found) {
+                        throw new RuntimeException("Illegal type: " + type);
+                    }
+                    index = i;
+                    break loop;
+                default:
+                    char_found = true;
+                    if (!delim) {
+                        buf.append(chars[i]);
+                    }
+            }
+        }
+        int brackets = 0;
+        if (index > 0) {
+            brackets = countBrackets(type.substring(index));
+        }
+        type = buf.toString();
+        buf.setLength(0);
+        for (int i = 0; i < brackets; i++) {
+            buf.append('[');
+        }
+        boolean found = false;
+        for (int i = Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) {
+            if (Constants.TYPE_NAMES[i].equals(type)) {
+                found = true;
+                buf.append(Constants.SHORT_TYPE_NAMES[i]);
+            }
+        }
+        if (!found) {
+            buf.append('L').append(type.replace('.', '/')).append(';');
+        }
+        return buf.toString();
+    }
+
+
+    private static int countBrackets( String brackets ) {
+        char[] chars = brackets.toCharArray();
+        int count = 0;
+        boolean open = false;
+        for (int i = 0; i < chars.length; i++) {
+            switch (chars[i]) {
+                case '[':
+                    if (open) {
+                        throw new RuntimeException("Illegally nested brackets:" + brackets);
+                    }
+                    open = true;
+                    break;
+                case ']':
+                    if (!open) {
+                        throw new RuntimeException("Illegally nested brackets:" + brackets);
+                    }
+                    open = false;
+                    count++;
+                    break;
+                default:
+                    // Don't care
+            }
+        }
+        if (open) {
+            throw new RuntimeException("Illegally nested brackets:" + brackets);
+        }
+        return count;
+    }
+
+
+    /**
+     * Return type of method signature as a byte value as defined in <em>Constants</em>
+     *
+     * @param  signature in format described above
+     * @return type of method signature
+     * @see    Constants
+     */
+    public static final byte typeOfMethodSignature( String signature ) throws ClassFormatException {
+        int index;
+        try {
+            if (signature.charAt(0) != '(') {
+                throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+            index = signature.lastIndexOf(')') + 1;
+            return typeOfSignature(signature.substring(index));
+        } catch (StringIndexOutOfBoundsException e) {
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+    }
+
+
+    /**
+     * Return type of signature as a byte value as defined in <em>Constants</em>
+     *
+     * @param  signature in format described above
+     * @return type of signature
+     * @see    Constants
+     */
+    public static final byte typeOfSignature( String signature ) throws ClassFormatException {
+        try {
+            switch (signature.charAt(0)) {
+                case 'B':
+                    return Constants.T_BYTE;
+                case 'C':
+                    return Constants.T_CHAR;
+                case 'D':
+                    return Constants.T_DOUBLE;
+                case 'F':
+                    return Constants.T_FLOAT;
+                case 'I':
+                    return Constants.T_INT;
+                case 'J':
+                    return Constants.T_LONG;
+                case 'L':
+                    return Constants.T_REFERENCE;
+                case '[':
+                    return Constants.T_ARRAY;
+                case 'V':
+                    return Constants.T_VOID;
+                case 'Z':
+                    return Constants.T_BOOLEAN;
+                case 'S':
+                    return Constants.T_SHORT;
+                default:
+                    throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+        } catch (StringIndexOutOfBoundsException e) {
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+    }
+
+
+    /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload"
+     */
+    public static short searchOpcode( String name ) {
+        name = name.toLowerCase(Locale.ENGLISH);
+        for (short i = 0; i < Constants.OPCODE_NAMES.length; i++) {
+            if (Constants.OPCODE_NAMES[i].equals(name)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Convert (signed) byte to (unsigned) short value, i.e., all negative
+     * values become positive.
+     */
+    private static final short byteToShort( byte b ) {
+        return (b < 0) ? (short) (256 + b) : (short) b;
+    }
+
+
+    /** Convert bytes into hexidecimal string
+     *
+     * @return bytes as hexidecimal string, e.g. 00 FA 12 ...
+     */
+    public static final String toHexString( byte[] bytes ) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < bytes.length; i++) {
+            short b = byteToShort(bytes[i]);
+            String hex = Integer.toString(b, 0x10);
+            if (b < 0x10) {
+                buf.append('0');
+            }
+            buf.append(hex);
+            if (i < bytes.length - 1) {
+                buf.append(' ');
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * Return a string for an integer justified left or right and filled up with
+     * `fill' characters if necessary.
+     *
+     * @param i integer to format
+     * @param length length of desired string
+     * @param left_justify format left or right
+     * @param fill fill character
+     * @return formatted int
+     */
+    public static final String format( int i, int length, boolean left_justify, char fill ) {
+        return fillup(Integer.toString(i), length, left_justify, fill);
+    }
+
+
+    /**
+     * Fillup char with up to length characters with char `fill' and justify it left or right.
+     *
+     * @param str string to format
+     * @param length length of desired string
+     * @param left_justify format left or right
+     * @param fill fill character
+     * @return formatted string
+     */
+    public static final String fillup( String str, int length, boolean left_justify, char fill ) {
+        int len = length - str.length();
+        char[] buf = new char[(len < 0) ? 0 : len];
+        for (int j = 0; j < buf.length; j++) {
+            buf[j] = fill;
+        }
+        if (left_justify) {
+            return str + new String(buf);
+        }
+        return new String(buf) + str;
+    }
+
+
+    static final boolean equals( byte[] a, byte[] b ) {
+        int size;
+        if ((size = a.length) != b.length) {
+            return false;
+        }
+        for (int i = 0; i < size; i++) {
+            if (a[i] != b[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    public static final void printArray( PrintStream out, Object[] obj ) {
+        out.println(printArray(obj, true));
+    }
+
+
+    public static final void printArray( PrintWriter out, Object[] obj ) {
+        out.println(printArray(obj, true));
+    }
+
+
+    public static final String printArray( Object[] obj ) {
+        return printArray(obj, true);
+    }
+
+
+    public static final String printArray( Object[] obj, boolean braces ) {
+        return printArray(obj, braces, false);
+    }
+
+
+    public static final String printArray( Object[] obj, boolean braces, boolean quote ) {
+        if (obj == null) {
+            return null;
+        }
+        StringBuffer buf = new StringBuffer();
+        if (braces) {
+            buf.append('{');
+        }
+        for (int i = 0; i < obj.length; i++) {
+            if (obj[i] != null) {
+                buf.append((quote ? "\"" : "")).append(obj[i].toString()).append(
+                        (quote ? "\"" : ""));
+            } else {
+                buf.append("null");
+            }
+            if (i < obj.length - 1) {
+                buf.append(", ");
+            }
+        }
+        if (braces) {
+            buf.append('}');
+        }
+        return buf.toString();
+    }
+
+
+    /** @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _)
+     */
+    public static boolean isJavaIdentifierPart( char ch ) {
+        return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))
+                || ((ch >= '0') && (ch <= '9')) || (ch == '_');
+    }
+
+
+    /** Encode byte array it into Java identifier string, i.e., a string
+     * that only contains the following characters: (a, ... z, A, ... Z,
+     * 0, ... 9, _, $).  The encoding algorithm itself is not too
+     * clever: if the current byte's ASCII value already is a valid Java
+     * identifier part, leave it as it is. Otherwise it writes the
+     * escape character($) followed by <p><ul><li> the ASCII value as a
+     * hexadecimal string, if the value is not in the range
+     * 200..247</li> <li>a Java identifier char not used in a lowercase
+     * hexadecimal string, if the value is in the range
+     * 200..247</li><ul></p>
+     *
+     * <p>This operation inflates the original byte array by roughly 40-50%</p>
+     *
+     * @param bytes the byte array to convert
+     * @param compress use gzip to minimize string
+     */
+    public static String encode( byte[] bytes, boolean compress ) throws IOException {
+        if (compress) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            GZIPOutputStream gos = new GZIPOutputStream(baos);
+            gos.write(bytes, 0, bytes.length);
+            gos.close();
+            baos.close();
+            bytes = baos.toByteArray();
+        }
+        CharArrayWriter caw = new CharArrayWriter();
+        JavaWriter jw = new JavaWriter(caw);
+        for (int i = 0; i < bytes.length; i++) {
+            int in = bytes[i] & 0x000000ff; // Normalize to unsigned
+            jw.write(in);
+        }
+        return caw.toString();
+    }
+
+
+    /** Decode a string back to a byte array.
+     *
+     * @param s the string to convert
+     * @param uncompress use gzip to uncompress the stream of bytes
+     */
+    public static byte[] decode( String s, boolean uncompress ) throws IOException {
+        char[] chars = s.toCharArray();
+        CharArrayReader car = new CharArrayReader(chars);
+        JavaReader jr = new JavaReader(car);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        int ch;
+        while ((ch = jr.read()) >= 0) {
+            bos.write(ch);
+        }
+        bos.close();
+        car.close();
+        jr.close();
+        byte[] bytes = bos.toByteArray();
+        if (uncompress) {
+            GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
+            byte[] tmp = new byte[bytes.length * 3]; // Rough estimate
+            int count = 0;
+            int b;
+            while ((b = gis.read()) >= 0) {
+                tmp[count++] = (byte) b;
+            }
+            bytes = new byte[count];
+            System.arraycopy(tmp, 0, bytes, 0, count);
+        }
+        return bytes;
+    }
+
+    // A-Z, g-z, _, $
+    private static final int FREE_CHARS = 48;
+    static int[] CHAR_MAP = new int[FREE_CHARS];
+    static int[] MAP_CHAR = new int[256]; // Reverse map
+    private static final char ESCAPE_CHAR = '$';
+    static {
+        int j = 0;
+        for (int i = 'A'; i <= 'Z'; i++) {
+            CHAR_MAP[j] = i;
+            MAP_CHAR[i] = j;
+            j++;
+        }
+        for (int i = 'g'; i <= 'z'; i++) {
+            CHAR_MAP[j] = i;
+            MAP_CHAR[i] = j;
+            j++;
+        }
+        CHAR_MAP[j] = '$';
+        MAP_CHAR['$'] = j;
+        j++;
+        CHAR_MAP[j] = '_';
+        MAP_CHAR['_'] = j;
+    }
+
+    /** Decode characters into bytes.
+     * Used by <a href="Utility.html#decode(java.lang.String, boolean)">decode()</a>
+     */
+    private static class JavaReader extends FilterReader {
+
+        public JavaReader(Reader in) {
+            super(in);
+        }
+
+
+        public int read() throws IOException {
+            int b = in.read();
+            if (b != ESCAPE_CHAR) {
+                return b;
+            }
+            int i = in.read();
+            if (i < 0) {
+                return -1;
+            }
+            if (((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape
+                int j = in.read();
+                if (j < 0) {
+                    return -1;
+                }
+                char[] tmp = {
+                        (char) i, (char) j
+                };
+                int s = Integer.parseInt(new String(tmp), 16);
+                return s;
+            }
+            return MAP_CHAR[i];
+        }
+
+
+        public int read( char[] cbuf, int off, int len ) throws IOException {
+            for (int i = 0; i < len; i++) {
+                cbuf[off + i] = (char) read();
+            }
+            return len;
+        }
+    }
+
+    /** Encode bytes into valid java identifier characters.
+     * Used by <a href="Utility.html#encode(byte[], boolean)">encode()</a>
+     */
+    private static class JavaWriter extends FilterWriter {
+
+        public JavaWriter(Writer out) {
+            super(out);
+        }
+
+
+        public void write( int b ) throws IOException {
+            if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) {
+                out.write(b);
+            } else {
+                out.write(ESCAPE_CHAR); // Escape character
+                // Special escape
+                if (b >= 0 && b < FREE_CHARS) {
+                    out.write(CHAR_MAP[b]);
+                } else { // Normal escape
+                    char[] tmp = Integer.toHexString(b).toCharArray();
+                    if (tmp.length == 1) {
+                        out.write('0');
+                        out.write(tmp[0]);
+                    } else {
+                        out.write(tmp[0]);
+                        out.write(tmp[1]);
+                    }
+                }
+            }
+        }
+
+
+        public void write( char[] cbuf, int off, int len ) throws IOException {
+            for (int i = 0; i < len; i++) {
+                write(cbuf[off + i]);
+            }
+        }
+
+
+        public void write( String str, int off, int len ) throws IOException {
+            write(str.toCharArray(), off, len);
+        }
+    }
+
+
+    /**
+     * Escape all occurences of newline chars '\n', quotes \", etc.
+     */
+    public static final String convertString( String label ) {
+        char[] ch = label.toCharArray();
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < ch.length; i++) {
+            switch (ch[i]) {
+                case '\n':
+                    buf.append("\\n");
+                    break;
+                case '\r':
+                    buf.append("\\r");
+                    break;
+                case '\"':
+                    buf.append("\\\"");
+                    break;
+                case '\'':
+                    buf.append("\\'");
+                    break;
+                case '\\':
+                    buf.append("\\\\");
+                    break;
+                default:
+                    buf.append(ch[i]);
+                    break;
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * Converts a list of AnnotationGen objects into a set of attributes 
+     * that can be attached to the class file.
+     *
+     * @param cp The constant pool gen where we can create the necessary name refs
+     * @param vec A list of AnnotationGen objects
+     */
+    public static Attribute[] getAnnotationAttributes(ConstantPoolGen cp,List vec) {
+       
+       if (vec.isEmpty()) return new Attribute[0];
+       
+       try {
+               int countVisible   = 0;
+               int countInvisible = 0;
+       
+               //  put the annotations in the right output stream
+               for (int i=0; i<vec.size(); i++) {
+                       AnnotationEntryGen a = (AnnotationEntryGen)vec.get(i);
+                       if (a.isRuntimeVisible()) countVisible++;
+                       else                       countInvisible++;
+               }
+       
+               ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream();
+               ByteArrayOutputStream riaBytes = new ByteArrayOutputStream();
+               DataOutputStream rvaDos = new DataOutputStream(rvaBytes);
+               DataOutputStream riaDos = new DataOutputStream(riaBytes);
+       
+               rvaDos.writeShort(countVisible);
+               riaDos.writeShort(countInvisible);
+
+               // put the annotations in the right output stream
+               for (int i=0; i<vec.size(); i++) {
+                       AnnotationEntryGen a = (AnnotationEntryGen)vec.get(i);
+                       if (a.isRuntimeVisible()) a.dump(rvaDos);
+                       else                       a.dump(riaDos);
+               }
+
+      rvaDos.close();
+      riaDos.close();
+      
+      byte[] rvaData = rvaBytes.toByteArray();
+      byte[] riaData = riaBytes.toByteArray();
+      
+      int rvaIndex = -1;
+      int riaIndex = -1;
+      
+      if (rvaData.length>2) rvaIndex = cp.addUtf8("RuntimeVisibleAnnotations");
+      if (riaData.length>2) riaIndex = cp.addUtf8("RuntimeInvisibleAnnotations");
+
+       List newAttributes = new ArrayList();
+       if (rvaData.length>2) {
+               
+               newAttributes.add(
+                 new RuntimeVisibleAnnotations(rvaIndex,rvaData.length,new DataInputStream(new ByteArrayInputStream(rvaData)),cp.getConstantPool()));
+       }
+       if (riaData.length>2) {
+               newAttributes.add(
+                 new RuntimeInvisibleAnnotations(riaIndex,riaData.length,new DataInputStream(new ByteArrayInputStream(riaData)),cp.getConstantPool()));
+       }
+
+       return (Attribute[])newAttributes.toArray(new Attribute[newAttributes.size()]);
+       } catch (IOException e) {
+               System.err.println("IOException whilst processing annotations");
+               e.printStackTrace();
+       }
+       return null;
+    }
+
+
+    /**
+        * Annotations against a class are stored in one of four attribute kinds:
+        * - RuntimeVisibleParameterAnnotations
+        * - RuntimeInvisibleParameterAnnotations
+        */
+       public static Attribute[] getParameterAnnotationAttributes(
+                       ConstantPoolGen cp,
+                       List[] /*Array of lists, array size depends on #params */vec)
+       {
+               int visCount[] = new int[vec.length];
+               int totalVisCount = 0;
+               int invisCount[] = new int[vec.length];
+               int totalInvisCount = 0;
+               try
+               {
+                       for (int i = 0; i < vec.length; i++)
+                       {
+                               List l = vec[i];
+                               if (l != null)
+                               {
+                                       for (Iterator iter = l.iterator(); iter.hasNext();)
+                                       {
+                                               AnnotationEntryGen element = (AnnotationEntryGen) iter.next();
+                                               if (element.isRuntimeVisible())
+                                               {
+                                                       visCount[i]++;
+                                                       totalVisCount++;
+                                               }
+                                               else
+                                               {
+                                                       invisCount[i]++;
+                                                       totalInvisCount++;
+                                               }
+                                       }
+                               }
+                       }
+                       // Lets do the visible ones
+                       ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream();
+                       DataOutputStream rvaDos = new DataOutputStream(rvaBytes);
+                       rvaDos.writeByte(vec.length); // First goes number of parameters
+                       for (int i = 0; i < vec.length; i++)
+                       {
+                               rvaDos.writeShort(visCount[i]);
+                               if (visCount[i] > 0)
+                               {
+                                       List l = vec[i];
+                                       for (Iterator iter = l.iterator(); iter.hasNext();)
+                                       {
+                                               AnnotationEntryGen element = (AnnotationEntryGen) iter.next();
+                                               if (element.isRuntimeVisible())
+                                                       element.dump(rvaDos);
+                                       }
+                               }
+                       }
+                       rvaDos.close();
+                       // Lets do the invisible ones
+                       ByteArrayOutputStream riaBytes = new ByteArrayOutputStream();
+                       DataOutputStream riaDos = new DataOutputStream(riaBytes);
+                       riaDos.writeByte(vec.length); // First goes number of parameters
+                       for (int i = 0; i < vec.length; i++)
+                       {
+                               riaDos.writeShort(invisCount[i]);
+                               if (invisCount[i] > 0)
+                               {
+                                       List l = vec[i];
+                                       for (Iterator iter = l.iterator(); iter.hasNext();)
+                                       {
+                                               AnnotationEntryGen element = (AnnotationEntryGen) iter.next();
+                                               if (!element.isRuntimeVisible())
+                                                       element.dump(riaDos);
+                                       }
+                               }
+                       }
+                       riaDos.close();
+                       byte[] rvaData = rvaBytes.toByteArray();
+                       byte[] riaData = riaBytes.toByteArray();
+                       int rvaIndex = -1;
+                       int riaIndex = -1;
+                       if (totalVisCount > 0)
+                               rvaIndex = cp.addUtf8("RuntimeVisibleParameterAnnotations");
+                       if (totalInvisCount > 0)
+                               riaIndex = cp.addUtf8("RuntimeInvisibleParameterAnnotations");
+                       List newAttributes = new ArrayList();
+                       if (totalVisCount > 0)
+                       {
+                               newAttributes
+                                               .add(new RuntimeVisibleParameterAnnotations(rvaIndex,
+                                                               rvaData.length, new DataInputStream(new ByteArrayInputStream(rvaData)), cp.getConstantPool()));
+                       }
+                       if (totalInvisCount > 0)
+                       {
+                               newAttributes
+                                               .add(new RuntimeInvisibleParameterAnnotations(riaIndex,
+                                                               riaData.length, new DataInputStream(new ByteArrayInputStream(riaData)), cp.getConstantPool()));
+                       }
+                       return (Attribute[]) newAttributes.toArray(new Attribute[newAttributes.size()]);
+               }
+               catch (IOException e)
+               {
+                       System.err
+                                       .println("IOException whilst processing parameter annotations");
+                       e.printStackTrace();
+               }
+               return null;
+       }
+
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/Visitor.java b/java/org/apache/tomcat/util/bcel/classfile/Visitor.java
new file mode 100644 (file)
index 0000000..1d8305f
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.classfile;
+
+/**
+ * Interface to make use of the Visitor pattern programming style. I.e. a class
+ * that implements this interface can traverse the contents of a Java class just
+ * by calling the `accept' method which all classes have.
+ * 
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface Visitor
+{
+       public void visitCode(Code obj);
+
+       public void visitCodeException(CodeException obj);
+
+       public void visitConstantClass(ConstantClass obj);
+
+       public void visitConstantDouble(ConstantDouble obj);
+
+       public void visitConstantFieldref(ConstantFieldref obj);
+
+       public void visitConstantFloat(ConstantFloat obj);
+
+       public void visitConstantInteger(ConstantInteger obj);
+
+       public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
+
+       public void visitConstantLong(ConstantLong obj);
+
+       public void visitConstantMethodref(ConstantMethodref obj);
+
+       public void visitConstantNameAndType(ConstantNameAndType obj);
+
+       public void visitConstantPool(ConstantPool obj);
+
+       public void visitConstantString(ConstantString obj);
+
+       public void visitConstantUtf8(ConstantUtf8 obj);
+
+       public void visitConstantValue(ConstantValue obj);
+
+       public void visitDeprecated(Deprecated obj);
+
+       public void visitExceptionTable(ExceptionTable obj);
+
+       public void visitField(Field obj);
+
+       public void visitInnerClass(InnerClass obj);
+
+       public void visitInnerClasses(InnerClasses obj);
+
+       public void visitJavaClass(JavaClass obj);
+
+       public void visitLineNumber(LineNumber obj);
+
+       public void visitLineNumberTable(LineNumberTable obj);
+
+       public void visitLocalVariable(LocalVariable obj);
+
+       public void visitLocalVariableTable(LocalVariableTable obj);
+
+       public void visitMethod(Method obj);
+
+       public void visitSignature(Signature obj);
+
+       public void visitSourceFile(SourceFile obj);
+
+       public void visitSynthetic(Synthetic obj);
+
+       public void visitUnknown(Unknown obj);
+
+       public void visitStackMap(StackMap obj);
+
+       public void visitStackMapEntry(StackMapEntry obj);
+
+       public void visitStackMapTable(StackMapTable obj);
+
+       public void visitStackMapTableEntry(StackMapTableEntry obj);
+
+       public void visitAnnotation(Annotations obj);
+
+       public void visitParameterAnnotation(ParameterAnnotations obj);
+
+       public void visitAnnotationEntry(AnnotationEntry obj);
+
+       public void visitAnnotationDefault(AnnotationDefault obj);
+
+       public void visitLocalVariableTypeTable(LocalVariableTypeTable obj);
+
+       public void visitEnclosingMethod(EnclosingMethod obj);
+}
diff --git a/java/org/apache/tomcat/util/bcel/classfile/package.html b/java/org/apache/tomcat/util/bcel/classfile/package.html
new file mode 100644 (file)
index 0000000..2bf7c28
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+$Id$
+-->
+</head>
+<body bgcolor="white">
+<p>
+This package contains the classes that describe the structure of a
+Java class file and a class file parser.
+</p>
+</body>
+</html>
diff --git a/java/org/apache/tomcat/util/bcel/generic/AALOAD.java b/java/org/apache/tomcat/util/bcel/generic/AALOAD.java
new file mode 100644 (file)
index 0000000..a5a6e84
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * AALOAD - Load reference from array
+ * <PRE>Stack: ..., arrayref, index -&gt; value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class AALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load reference from array
+     */
+    public AALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.AALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitAALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/AASTORE.java b/java/org/apache/tomcat/util/bcel/generic/AASTORE.java
new file mode 100644 (file)
index 0000000..71534ff
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * AASTORE -  Store into reference array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class AASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store into reference array
+     */
+    public AASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.AASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitAASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ACONST_NULL.java b/java/org/apache/tomcat/util/bcel/generic/ACONST_NULL.java
new file mode 100644 (file)
index 0000000..6b68d0e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ACONST_NULL - Push null reference
+ * <PRE>Stack: ... -&gt; ..., null</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction {
+
+    /** 
+     * Push null reference
+     */
+    public ACONST_NULL() {
+        super(org.apache.tomcat.util.bcel.Constants.ACONST_NULL, (short) 1);
+    }
+
+
+    /** @return Type.NULL
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.NULL;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitACONST_NULL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ALOAD.java b/java/org/apache/tomcat/util/bcel/generic/ALOAD.java
new file mode 100644 (file)
index 0000000..8103368
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ALOAD - Load reference from local variable
+ * <PRE>Stack: ... -&gt; ..., objectref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ALOAD extends LoadInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.ALOAD, org.apache.tomcat.util.bcel.Constants.ALOAD_0);
+    }
+
+
+    /** Load reference from local variable
+     * @param n index of local variable
+     */
+    public ALOAD(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.ALOAD, org.apache.tomcat.util.bcel.Constants.ALOAD_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ANEWARRAY.java b/java/org/apache/tomcat/util/bcel/generic/ANEWARRAY.java
new file mode 100644 (file)
index 0000000..a359277
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * ANEWARRAY -  Create new array of references
+ * <PRE>Stack: ..., count -&gt; ..., arrayref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction,
+        ExceptionThrower, StackConsumer, StackProducer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ANEWARRAY() {
+    }
+
+
+    public ANEWARRAY(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.ANEWARRAY, index);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLoadClass(this);
+        v.visitAllocationInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitANEWARRAY(this);
+    }
+
+
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        Type t = getType(cpg);
+        if (t instanceof ArrayType) {
+            t = ((ArrayType) t).getBasicType();
+        }
+        return (t instanceof ObjectType) ? (ObjectType) t : null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ARETURN.java b/java/org/apache/tomcat/util/bcel/generic/ARETURN.java
new file mode 100644 (file)
index 0000000..b31ca25
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ARETURN -  Return reference from method
+ * <PRE>Stack: ..., objectref -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ARETURN extends ReturnInstruction {
+
+    /** 
+     * Return reference from method
+     */
+    public ARETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.ARETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitARETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ARRAYLENGTH.java b/java/org/apache/tomcat/util/bcel/generic/ARRAYLENGTH.java
new file mode 100644 (file)
index 0000000..11592ff
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ARRAYLENGTH -  Get length of array
+ * <PRE>Stack: ..., arrayref -&gt; ..., length</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ARRAYLENGTH extends Instruction implements ExceptionThrower, StackProducer, StackConsumer {
+
+    /** Get length of array
+     */
+    public ARRAYLENGTH() {
+        super(org.apache.tomcat.util.bcel.Constants.ARRAYLENGTH, (short) 1);
+    }
+
+
+    /** @return exceptions this instruction may cause
+     */
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitARRAYLENGTH(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ASTORE.java b/java/org/apache/tomcat/util/bcel/generic/ASTORE.java
new file mode 100644 (file)
index 0000000..43582b7
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ASTORE - Store reference into local variable
+ * <PRE>Stack ..., objectref -&gt; ... </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ASTORE extends StoreInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.ASTORE, org.apache.tomcat.util.bcel.Constants.ASTORE_0);
+    }
+
+
+    /** Store reference into local variable
+     * @param n index of local variable
+     */
+    public ASTORE(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.ASTORE, org.apache.tomcat.util.bcel.Constants.ASTORE_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ATHROW.java b/java/org/apache/tomcat/util/bcel/generic/ATHROW.java
new file mode 100644 (file)
index 0000000..e187d5b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ATHROW -  Throw exception
+ * <PRE>Stack: ..., objectref -&gt; objectref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower {
+
+    /** 
+     *  Throw exception
+     */
+    public ATHROW() {
+        super(org.apache.tomcat.util.bcel.Constants.ATHROW, (short) 1);
+    }
+
+
+    /** @return exceptions this instruction may cause
+     */
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.THROWABLE
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitUnconditionalBranch(this);
+        v.visitExceptionThrower(this);
+        v.visitATHROW(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/AllocationInstruction.java b/java/org/apache/tomcat/util/bcel/generic/AllocationInstruction.java
new file mode 100644 (file)
index 0000000..fd8c322
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote family of instructions that allocates space in the heap.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface AllocationInstruction {
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/AnnotationElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/AnnotationElementValueGen.java
new file mode 100644 (file)
index 0000000..dc1a468
--- /dev/null
@@ -0,0 +1,60 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.AnnotationElementValue;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+
+public class AnnotationElementValueGen extends ElementValueGen
+{
+       // For annotation element values, this is the annotation
+       private AnnotationEntryGen a;
+
+       public AnnotationElementValueGen(AnnotationEntryGen a, ConstantPoolGen cpool)
+       {
+               super(ANNOTATION, cpool);
+               this.a = a;
+       }
+
+       public AnnotationElementValueGen(int type, AnnotationEntryGen annotation,
+                       ConstantPoolGen cpool)
+       {
+               super(type, cpool);
+               if (type != ANNOTATION)
+                       throw new RuntimeException(
+                                       "Only element values of type annotation can be built with this ctor - type specified: " + type);
+               this.a = annotation;
+       }
+
+       public AnnotationElementValueGen(AnnotationElementValue value,
+                       ConstantPoolGen cpool, boolean copyPoolEntries)
+       {
+               super(ANNOTATION, cpool);
+               a = new AnnotationEntryGen(value.getAnnotationEntry(), cpool, copyPoolEntries);
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ANNOTATION == '@')
+               a.dump(dos);
+       }
+
+       public String stringifyValue()
+       {
+               throw new RuntimeException("Not implemented yet");
+       }
+
+       /**
+        * Return immutable variant of this AnnotationElementValueGen
+        */
+       public ElementValue getElementValue()
+       {
+               return new AnnotationElementValue(this.type, a.getAnnotation(), cpGen
+                               .getConstantPool());
+       }
+
+       public AnnotationEntryGen getAnnotation()
+       {
+               return a;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/AnnotationEntryGen.java b/java/org/apache/tomcat/util/bcel/generic/AnnotationEntryGen.java
new file mode 100755 (executable)
index 0000000..ee0d0be
--- /dev/null
@@ -0,0 +1,190 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ElementValuePair;
+
+
+public class AnnotationEntryGen
+{
+       private int typeIndex;
+
+       private List /* ElementNameValuePairGen */evs;
+
+       private ConstantPoolGen cpool;
+
+       private boolean isRuntimeVisible = false;
+
+       /**
+        * Here we are taking a fixed annotation of type Annotation and building a
+        * modifiable AnnotationGen object. If the pool passed in is for a different
+        * class file, then copyPoolEntries should have been passed as true as that
+        * will force us to do a deep copy of the annotation and move the cpool
+        * entries across. We need to copy the type and the element name value pairs
+        * and the visibility.
+        */
+       public AnnotationEntryGen(AnnotationEntry a, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               this.cpool = cpool;
+               if (copyPoolEntries)
+               {
+                       typeIndex = cpool.addUtf8(a.getAnnotationType());
+               }
+               else
+               {
+                       typeIndex = a.getAnnotationTypeIndex();
+               }
+               isRuntimeVisible = a.isRuntimeVisible();
+               evs = copyValues(a.getElementValuePairs(), cpool, copyPoolEntries);
+       }
+
+       private List copyValues(ElementValuePair[] in, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               List out = new ArrayList();
+               int l = in.length;
+               for (int i = 0; i < l; i++)
+               {
+                       ElementValuePair nvp = (ElementValuePair) in[i];
+                       out.add(new ElementValuePairGen(nvp, cpool, copyPoolEntries));
+               }
+               return out;
+       }
+
+       private AnnotationEntryGen(ConstantPoolGen cpool)
+       {
+               this.cpool = cpool;
+       }
+
+       /**
+        * Retrieve an immutable version of this AnnotationGen
+        */
+       public AnnotationEntry getAnnotation()
+       {
+               AnnotationEntry a = new AnnotationEntry(typeIndex, cpool.getConstantPool(),
+                               isRuntimeVisible);
+               for (Iterator iter = evs.iterator(); iter.hasNext();)
+               {
+                       ElementValuePairGen element = (ElementValuePairGen) iter
+                                       .next();
+                       a.addElementNameValuePair(element.getElementNameValuePair());
+               }
+               return a;
+       }
+
+       public AnnotationEntryGen(ObjectType type,
+                       List /* ElementNameValuePairGen */elements, boolean vis,
+                       ConstantPoolGen cpool)
+       {
+               this.cpool = cpool;
+               this.typeIndex = cpool.addUtf8(type.getSignature());
+               evs = elements;
+               isRuntimeVisible = vis;
+       }
+
+       public static AnnotationEntryGen read(DataInputStream dis,
+                       ConstantPoolGen cpool, boolean b) throws IOException
+       {
+               AnnotationEntryGen a = new AnnotationEntryGen(cpool);
+               a.typeIndex = dis.readUnsignedShort();
+               int elemValuePairCount = dis.readUnsignedShort();
+               for (int i = 0; i < elemValuePairCount; i++)
+               {
+                       int nidx = dis.readUnsignedShort();
+                       a.addElementNameValuePair(new ElementValuePairGen(nidx,
+                                       ElementValueGen.readElementValue(dis, cpool), cpool));
+               }
+               a.isRuntimeVisible(b);
+               return a;
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeShort(typeIndex); // u2 index of type name in cpool
+               dos.writeShort(evs.size()); // u2 element_value pair count
+               for (int i = 0; i < evs.size(); i++)
+               {
+                       ElementValuePairGen envp = (ElementValuePairGen) evs.get(i);
+                       envp.dump(dos);
+               }
+       }
+
+       public void addElementNameValuePair(ElementValuePairGen evp)
+       {
+               if (evs == null)
+                       evs = new ArrayList();
+               evs.add(evp);
+       }
+
+       public int getTypeIndex()
+       {
+               return typeIndex;
+       }
+
+       public final String getTypeSignature()
+       {
+               // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex);
+               ConstantUtf8 utf8 = (ConstantUtf8) cpool
+                               .getConstant(typeIndex/* c.getNameIndex() */);
+               return utf8.getBytes();
+       }
+
+       public final String getTypeName()
+       {
+               return getTypeSignature();// BCELBUG: Should I use this instead?
+                                                                       // Utility.signatureToString(getTypeSignature());
+       }
+
+       /**
+        * Returns list of ElementNameValuePair objects
+        */
+       public List getValues()
+       {
+               return evs;
+       }
+
+       public String toString()
+       {
+               StringBuffer s = new StringBuffer();
+               s.append("AnnotationGen:[" + getTypeName() + " #" + evs.size() + " {");
+               for (int i = 0; i < evs.size(); i++)
+               {
+                       s.append(evs.get(i));
+                       if (i + 1 < evs.size())
+                               s.append(",");
+               }
+               s.append("}]");
+               return s.toString();
+       }
+
+       public String toShortString()
+       {
+               StringBuffer s = new StringBuffer();
+               s.append("@" + getTypeName() + "(");
+               for (int i = 0; i < evs.size(); i++)
+               {
+                       s.append(evs.get(i));
+                       if (i + 1 < evs.size())
+                               s.append(",");
+               }
+               s.append(")");
+               return s.toString();
+       }
+
+       private void isRuntimeVisible(boolean b)
+       {
+               isRuntimeVisible = b;
+       }
+
+       public boolean isRuntimeVisible()
+       {
+               return isRuntimeVisible;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ArithmeticInstruction.java b/java/org/apache/tomcat/util/bcel/generic/ArithmeticInstruction.java
new file mode 100644 (file)
index 0000000..1337f63
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * Super class for the family of arithmetic instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction,
+        StackProducer, StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ArithmeticInstruction() {
+    }
+
+
+    /**
+     * @param opcode of instruction
+     */
+    protected ArithmeticInstruction(short opcode) {
+        super(opcode, (short) 1);
+    }
+
+
+    /** @return type associated with the instruction
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        switch (opcode) {
+            case Constants.DADD:
+            case Constants.DDIV:
+            case Constants.DMUL:
+            case Constants.DNEG:
+            case Constants.DREM:
+            case Constants.DSUB:
+                return Type.DOUBLE;
+            case Constants.FADD:
+            case Constants.FDIV:
+            case Constants.FMUL:
+            case Constants.FNEG:
+            case Constants.FREM:
+            case Constants.FSUB:
+                return Type.FLOAT;
+            case Constants.IADD:
+            case Constants.IAND:
+            case Constants.IDIV:
+            case Constants.IMUL:
+            case Constants.INEG:
+            case Constants.IOR:
+            case Constants.IREM:
+            case Constants.ISHL:
+            case Constants.ISHR:
+            case Constants.ISUB:
+            case Constants.IUSHR:
+            case Constants.IXOR:
+                return Type.INT;
+            case Constants.LADD:
+            case Constants.LAND:
+            case Constants.LDIV:
+            case Constants.LMUL:
+            case Constants.LNEG:
+            case Constants.LOR:
+            case Constants.LREM:
+            case Constants.LSHL:
+            case Constants.LSHR:
+            case Constants.LSUB:
+            case Constants.LUSHR:
+            case Constants.LXOR:
+                return Type.LONG;
+            default: // Never reached
+                throw new ClassGenException("Unknown type " + opcode);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ArrayElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/ArrayElementValueGen.java
new file mode 100644 (file)
index 0000000..f05b149
--- /dev/null
@@ -0,0 +1,109 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.tomcat.util.bcel.classfile.ArrayElementValue;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+
+public class ArrayElementValueGen extends ElementValueGen
+{
+       // J5TODO: Should we make this an array or a list? A list would be easier to
+       // modify ...
+       private List /* ElementValueGen */evalues;
+
+       public ArrayElementValueGen(ConstantPoolGen cp)
+       {
+               super(ARRAY, cp);
+               evalues = new ArrayList();
+       }
+
+       public ArrayElementValueGen(int type, ElementValue[] datums,
+                       ConstantPoolGen cpool)
+       {
+               super(type, cpool);
+               if (type != ARRAY)
+                       throw new RuntimeException(
+                                       "Only element values of type array can be built with this ctor - type specified: " + type);
+               this.evalues = new ArrayList();
+               for (int i = 0; i < datums.length; i++)
+               {
+                       evalues.add(datums[i]);
+               }
+       }
+
+       /**
+        * Return immutable variant of this ArrayElementValueGen
+        */
+       public ElementValue getElementValue()
+       {
+               ElementValue[] immutableData = new ElementValue[evalues.size()];
+               int i = 0;
+               for (Iterator iter = evalues.iterator(); iter.hasNext();)
+               {
+                       ElementValueGen element = (ElementValueGen) iter.next();
+                       immutableData[i++] = element.getElementValue();
+               }
+               return new ArrayElementValue(type, immutableData, cpGen
+                               .getConstantPool());
+       }
+
+       /**
+        * @param value
+        * @param cpool
+        */
+       public ArrayElementValueGen(ArrayElementValue value, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               super(ARRAY, cpool);
+               evalues = new ArrayList();
+               ElementValue[] in = value.getElementValuesArray();
+               for (int i = 0; i < in.length; i++)
+               {
+                       evalues.add(ElementValueGen.copy(in[i], cpool, copyPoolEntries));
+               }
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ARRAY == '[')
+               dos.writeShort(evalues.size());
+               for (Iterator iter = evalues.iterator(); iter.hasNext();)
+               {
+                       ElementValueGen element = (ElementValueGen) iter.next();
+                       element.dump(dos);
+               }
+       }
+
+       public String stringifyValue()
+       {
+               StringBuffer sb = new StringBuffer();
+               sb.append("[");
+               for (Iterator iter = evalues.iterator(); iter.hasNext();)
+               {
+                       ElementValueGen element = (ElementValueGen) iter.next();
+                       sb.append(element.stringifyValue());
+                       if (iter.hasNext())
+                               sb.append(",");
+               }
+               sb.append("]");
+               return sb.toString();
+       }
+
+       public List getElementValues()
+       {
+               return evalues;
+       }
+
+       public int getElementValuesSize()
+       {
+               return evalues.size();
+       }
+
+       public void addElement(ElementValueGen gen)
+       {
+               evalues.add(gen);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ArrayInstruction.java b/java/org/apache/tomcat/util/bcel/generic/ArrayInstruction.java
new file mode 100644 (file)
index 0000000..ac358d9
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Super class for instructions dealing with array access such as IALOAD.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class ArrayInstruction extends Instruction implements ExceptionThrower,
+        TypedInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ArrayInstruction() {
+    }
+
+
+    /**
+     * @param opcode of instruction
+     */
+    protected ArrayInstruction(short opcode) {
+        super(opcode, (short) 1);
+    }
+
+
+    public Class[] getExceptions() {
+        return org.apache.tomcat.util.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
+    }
+
+
+    /** @return type associated with the instruction
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        switch (opcode) {
+            case org.apache.tomcat.util.bcel.Constants.IALOAD:
+            case org.apache.tomcat.util.bcel.Constants.IASTORE:
+                return Type.INT;
+            case org.apache.tomcat.util.bcel.Constants.CALOAD:
+            case org.apache.tomcat.util.bcel.Constants.CASTORE:
+                return Type.CHAR;
+            case org.apache.tomcat.util.bcel.Constants.BALOAD:
+            case org.apache.tomcat.util.bcel.Constants.BASTORE:
+                return Type.BYTE;
+            case org.apache.tomcat.util.bcel.Constants.SALOAD:
+            case org.apache.tomcat.util.bcel.Constants.SASTORE:
+                return Type.SHORT;
+            case org.apache.tomcat.util.bcel.Constants.LALOAD:
+            case org.apache.tomcat.util.bcel.Constants.LASTORE:
+                return Type.LONG;
+            case org.apache.tomcat.util.bcel.Constants.DALOAD:
+            case org.apache.tomcat.util.bcel.Constants.DASTORE:
+                return Type.DOUBLE;
+            case org.apache.tomcat.util.bcel.Constants.FALOAD:
+            case org.apache.tomcat.util.bcel.Constants.FASTORE:
+                return Type.FLOAT;
+            case org.apache.tomcat.util.bcel.Constants.AALOAD:
+            case org.apache.tomcat.util.bcel.Constants.AASTORE:
+                return Type.OBJECT;
+            default:
+                throw new ClassGenException("Oops: unknown case in switch" + opcode);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ArrayType.java b/java/org/apache/tomcat/util/bcel/generic/ArrayType.java
new file mode 100644 (file)
index 0000000..58088a4
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Denotes array type, such as int[][]
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class ArrayType extends ReferenceType {
+
+    private int dimensions;
+    private Type basic_type;
+
+
+    /**
+     * Convenience constructor for array type, e.g. int[]
+     *
+     * @param type array type, e.g. T_INT
+     */
+    public ArrayType(byte type, int dimensions) {
+        this(BasicType.getType(type), dimensions);
+    }
+
+
+    /**
+     * Convenience constructor for reference array type, e.g. Object[]
+     *
+     * @param class_name complete name of class (java.lang.String, e.g.)
+     */
+    public ArrayType(String class_name, int dimensions) {
+        this(new ObjectType(class_name), dimensions);
+    }
+
+
+    /**
+     * Constructor for array of given type
+     *
+     * @param type type of array (may be an array itself)
+     */
+    public ArrayType(Type type, int dimensions) {
+        super(Constants.T_ARRAY, "<dummy>");
+        if ((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) {
+            throw new ClassGenException("Invalid number of dimensions: " + dimensions);
+        }
+        switch (type.getType()) {
+            case Constants.T_ARRAY:
+                ArrayType array = (ArrayType) type;
+                this.dimensions = dimensions + array.dimensions;
+                basic_type = array.basic_type;
+                break;
+            case Constants.T_VOID:
+                throw new ClassGenException("Invalid type: void[]");
+            default: // Basic type or reference
+                this.dimensions = dimensions;
+                basic_type = type;
+                break;
+        }
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < this.dimensions; i++) {
+            buf.append('[');
+        }
+        buf.append(basic_type.getSignature());
+        signature = buf.toString();
+    }
+
+
+    /**
+     * @return basic type of array, i.e., for int[][][] the basic type is int
+     */
+    public Type getBasicType() {
+        return basic_type;
+    }
+
+
+    /**
+     * @return element type of array, i.e., for int[][][] the element type is int[][]
+     */
+    public Type getElementType() {
+        if (dimensions == 1) {
+            return basic_type;
+        }
+        return new ArrayType(basic_type, dimensions - 1);
+    }
+
+
+    /** @return number of dimensions of array
+     */
+    public int getDimensions() {
+        return dimensions;
+    }
+
+
+    /** @return a hash code value for the object.
+     */
+    public int hashCode() {
+        return basic_type.hashCode() ^ dimensions;
+    }
+
+
+    /** @return true if both type objects refer to the same array type.
+     */
+    public boolean equals( Object _type ) {
+        if (_type instanceof ArrayType) {
+            ArrayType array = (ArrayType) _type;
+            return (array.dimensions == dimensions) && array.basic_type.equals(basic_type);
+        }
+        return false;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BALOAD.java b/java/org/apache/tomcat/util/bcel/generic/BALOAD.java
new file mode 100644 (file)
index 0000000..38d9c7b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * BALOAD - Load byte or boolean from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class BALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load byte or boolean from array
+     */
+    public BALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.BALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitBALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BASTORE.java b/java/org/apache/tomcat/util/bcel/generic/BASTORE.java
new file mode 100644 (file)
index 0000000..09726a4
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * BASTORE -  Store into byte or boolean array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class BASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store byte or boolean into array
+     */
+    public BASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.BASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitBASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BIPUSH.java b/java/org/apache/tomcat/util/bcel/generic/BIPUSH.java
new file mode 100644 (file)
index 0000000..a9474a9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * BIPUSH - Push byte on stack
+ *
+ * <PRE>Stack: ... -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class BIPUSH extends Instruction implements ConstantPushInstruction {
+
+    private byte b;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    BIPUSH() {
+    }
+
+
+    /** Push byte on stack
+     */
+    public BIPUSH(byte b) {
+        super(org.apache.tomcat.util.bcel.Constants.BIPUSH, (short) 2);
+        this.b = b;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        super.dump(out);
+        out.writeByte(b);
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + b;
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        length = 2;
+        b = bytes.readByte();
+    }
+
+
+    public Number getValue() {
+        return new Integer(b);
+    }
+
+
+    /** @return Type.BYTE
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.BYTE;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitBIPUSH(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BREAKPOINT.java b/java/org/apache/tomcat/util/bcel/generic/BREAKPOINT.java
new file mode 100644 (file)
index 0000000..f3454bf
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * BREAKPOINT, JVM dependent, ignored by default
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class BREAKPOINT extends Instruction {
+
+    public BREAKPOINT() {
+        super(org.apache.tomcat.util.bcel.Constants.BREAKPOINT, (short) 1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitBREAKPOINT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BasicType.java b/java/org/apache/tomcat/util/bcel/generic/BasicType.java
new file mode 100644 (file)
index 0000000..8445f6a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Denotes basic type such as int.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class BasicType extends Type {
+
+    /**
+     * Constructor for basic types such as int, long, `void'
+     *
+     * @param type one of T_INT, T_BOOLEAN, ..., T_VOID
+     * @see org.apache.tomcat.util.bcel.Constants
+     */
+    BasicType(byte type) {
+        super(type, Constants.SHORT_TYPE_NAMES[type]);
+        if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) {
+            throw new ClassGenException("Invalid type: " + type);
+        }
+    }
+
+
+    public static final BasicType getType( byte type ) {
+        switch (type) {
+            case Constants.T_VOID:
+                return VOID;
+            case Constants.T_BOOLEAN:
+                return BOOLEAN;
+            case Constants.T_BYTE:
+                return BYTE;
+            case Constants.T_SHORT:
+                return SHORT;
+            case Constants.T_CHAR:
+                return CHAR;
+            case Constants.T_INT:
+                return INT;
+            case Constants.T_LONG:
+                return LONG;
+            case Constants.T_DOUBLE:
+                return DOUBLE;
+            case Constants.T_FLOAT:
+                return FLOAT;
+            default:
+                throw new ClassGenException("Invalid type: " + type);
+        }
+    }
+
+
+    /** @return a hash code value for the object.
+     */
+    public int hashCode() {
+        return type;
+    }
+
+
+    /** @return true if both type objects refer to the same type
+     */
+    public boolean equals( Object _type ) {
+        return (_type instanceof BasicType) ? ((BasicType) _type).type == this.type : false;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BranchHandle.java b/java/org/apache/tomcat/util/bcel/generic/BranchHandle.java
new file mode 100644 (file)
index 0000000..bd436d9
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * BranchHandle is returned by specialized InstructionList.append() whenever a
+ * BranchInstruction is appended. This is useful when the target of this
+ * instruction is not known at time of creation and must be set later
+ * via setTarget().
+ *
+ * @see InstructionHandle
+ * @see Instruction
+ * @see InstructionList
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class BranchHandle extends InstructionHandle {
+
+    private BranchInstruction bi; // An alias in fact, but saves lots of casts
+
+
+    private BranchHandle(BranchInstruction i) {
+        super(i);
+        bi = i;
+    }
+
+    /** Factory methods.
+     */
+    private static BranchHandle bh_list = null; // List of reusable handles
+
+
+    static final BranchHandle getBranchHandle( BranchInstruction i ) {
+        if (bh_list == null) {
+            return new BranchHandle(i);
+        }
+        BranchHandle bh = bh_list;
+        bh_list = (BranchHandle) bh.next;
+        bh.setInstruction(i);
+        return bh;
+    }
+
+
+    /** Handle adds itself to the list of resuable handles.
+     */
+    protected void addHandle() {
+        next = bh_list;
+        bh_list = this;
+    }
+
+
+    /* Override InstructionHandle methods: delegate to branch instruction.
+     * Through this overriding all access to the private i_position field should
+     * be prevented.
+     */
+    public int getPosition() {
+        return bi.position;
+    }
+
+
+    void setPosition( int pos ) {
+        i_position = bi.position = pos;
+    }
+
+
+    protected int updatePosition( int offset, int max_offset ) {
+        int x = bi.updatePosition(offset, max_offset);
+        i_position = bi.position;
+        return x;
+    }
+
+
+    /**
+     * Pass new target to instruction.
+     */
+    public void setTarget( InstructionHandle ih ) {
+        bi.setTarget(ih);
+    }
+
+
+    /**
+     * Update target of instruction.
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        bi.updateTarget(old_ih, new_ih);
+    }
+
+
+    /**
+     * @return target of instruction.
+     */
+    public InstructionHandle getTarget() {
+        return bi.getTarget();
+    }
+
+
+    /** 
+     * Set new contents. Old instruction is disposed and may not be used anymore.
+     */
+    public void setInstruction( Instruction i ) {
+        super.setInstruction(i);
+        if (!(i instanceof BranchInstruction)) {
+            throw new ClassGenException("Assigning " + i
+                    + " to branch handle which is not a branch instruction");
+        }
+        bi = (BranchInstruction) i;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/BranchInstruction.java b/java/org/apache/tomcat/util/bcel/generic/BranchInstruction.java
new file mode 100644 (file)
index 0000000..3f2c2e7
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * Abstract super class for branching instructions like GOTO, IFEQ, etc..
+ * Branch instructions may have a variable length, namely GOTO, JSR, 
+ * LOOKUPSWITCH and TABLESWITCH.
+ *
+ * @see InstructionList
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class BranchInstruction extends Instruction implements InstructionTargeter {
+
+    protected int index; // Branch target relative to this instruction
+    protected InstructionHandle target; // Target object in instruction list
+    protected int position; // Byte code offset
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    BranchInstruction() {
+    }
+
+
+    /** Common super constructor
+     * @param opcode Instruction opcode
+     * @param target instruction to branch to
+     */
+    protected BranchInstruction(short opcode, InstructionHandle target) {
+        super(opcode, (short) 3);
+        setTarget(target);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        index = getTargetOffset();
+        if (Math.abs(index) >= 32767) {
+            throw new ClassGenException("Branch target offset too large for short: " + index);
+        }
+        out.writeShort(index); // May be negative, i.e., point backwards
+    }
+
+
+    /**
+     * @param _target branch target
+     * @return the offset to  `target' relative to this instruction
+     */
+    protected int getTargetOffset( InstructionHandle _target ) {
+        if (_target == null) {
+            throw new ClassGenException("Target of " + super.toString(true)
+                    + " is invalid null handle");
+        }
+        int t = _target.getPosition();
+        if (t < 0) {
+            throw new ClassGenException("Invalid branch target position offset for "
+                    + super.toString(true) + ":" + t + ":" + _target);
+        }
+        return t - position;
+    }
+
+
+    /**
+     * @return the offset to this instruction's target
+     */
+    protected int getTargetOffset() {
+        return getTargetOffset(target);
+    }
+
+
+    /**
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
+     *
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
+     */
+    protected int updatePosition( int offset, int max_offset ) {
+        position += offset;
+        return 0;
+    }
+
+
+    /**
+     * Long output format:
+     *
+     * &lt;position in byte code&gt;
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" 
+     * "("&lt;length of instruction&gt;")"
+     * "&lt;"&lt;target instruction&gt;"&gt;" "@"&lt;branch target offset&gt;
+     *
+     * @param verbose long/short format switch
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        String s = super.toString(verbose);
+        String t = "null";
+        if (verbose) {
+            if (target != null) {
+                if (target.getInstruction() == this) {
+                    t = "<points to itself>";
+                } else if (target.getInstruction() == null) {
+                    t = "<null instruction!!!?>";
+                } else {
+                    t = target.getInstruction().toString(false); // Avoid circles
+                }
+            }
+        } else {
+            if (target != null) {
+                index = getTargetOffset();
+                t = "" + (index + position);
+            }
+        }
+        return s + " -> " + t;
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file. Conversion to a InstructionHandle
+     * is done in InstructionList(byte[]).
+     *
+     * @param bytes input stream
+     * @param wide wide prefix?
+     * @see InstructionList
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        length = 3;
+        index = bytes.readShort();
+    }
+
+
+    /**
+     * @return target offset in byte code
+     */
+    public final int getIndex() {
+        return index;
+    }
+
+
+    /**
+     * @return target of branch instruction
+     */
+    public InstructionHandle getTarget() {
+        return target;
+    }
+
+
+    /**
+     * Set branch target
+     * @param target branch target
+     */
+    public void setTarget( InstructionHandle target ) {
+        notifyTarget(this.target, target, this);
+        this.target = target;
+    }
+
+
+    /**
+     * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
+     */
+    static final void notifyTarget( InstructionHandle old_ih, InstructionHandle new_ih,
+            InstructionTargeter t ) {
+        if (old_ih != null) {
+            old_ih.removeTargeter(t);
+        }
+        if (new_ih != null) {
+            new_ih.addTargeter(t);
+        }
+    }
+
+
+    /**
+     * @param old_ih old target
+     * @param new_ih new target
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        if (target == old_ih) {
+            setTarget(new_ih);
+        } else {
+            throw new ClassGenException("Not targeting " + old_ih + ", but " + target);
+        }
+    }
+
+
+    /**
+     * @return true, if ih is target of this instruction
+     */
+    public boolean containsTarget( InstructionHandle ih ) {
+        return (target == ih);
+    }
+
+
+    /**
+     * Inform target that it's not targeted anymore.
+     */
+    void dispose() {
+        setTarget(null);
+        index = -1;
+        position = -1;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CALOAD.java b/java/org/apache/tomcat/util/bcel/generic/CALOAD.java
new file mode 100644 (file)
index 0000000..e777965
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * CALOAD - Load char from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class CALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load char from array
+     */
+    public CALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.CALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitCALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CASTORE.java b/java/org/apache/tomcat/util/bcel/generic/CASTORE.java
new file mode 100644 (file)
index 0000000..060f35b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * CASTORE -  Store into char array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class CASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store char into array
+     */
+    public CASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.CASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitCASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CHECKCAST.java b/java/org/apache/tomcat/util/bcel/generic/CHECKCAST.java
new file mode 100644 (file)
index 0000000..181a3c0
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * CHECKCAST - Check whether object is of given type
+ * <PRE>Stack: ..., objectref -&gt; ..., objectref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer,
+        StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    CHECKCAST() {
+    }
+
+
+    /** Check whether object is of given type
+     * @param index index to class in constant pool
+     */
+    public CHECKCAST(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.CHECKCAST, index);
+    }
+
+
+    /** @return exceptions this instruction may cause
+     */
+    public Class[] getExceptions() {
+        Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.CLASS_CAST_EXCEPTION;
+        return cs;
+    }
+
+
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        Type t = getType(cpg);
+        if (t instanceof ArrayType) {
+            t = ((ArrayType) t).getBasicType();
+        }
+        return (t instanceof ObjectType) ? (ObjectType) t : null;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLoadClass(this);
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitCHECKCAST(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CPInstruction.java b/java/org/apache/tomcat/util/bcel/generic/CPInstruction.java
new file mode 100644 (file)
index 0000000..eaf3e16
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.classfile.ConstantClass;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * Abstract super class for instructions that use an index into the 
+ * constant pool such as LDC, INVOKEVIRTUAL, etc.
+ *
+ * @see ConstantPoolGen
+ * @see LDC
+ * @see INVOKEVIRTUAL
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class CPInstruction extends Instruction implements TypedInstruction,
+        IndexedInstruction {
+
+    protected int index; // index to constant pool
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    CPInstruction() {
+    }
+
+
+    /**
+     * @param index to constant pool
+     */
+    protected CPInstruction(short opcode, int index) {
+        super(opcode, (short) 3);
+        setIndex(index);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        out.writeShort(index);
+    }
+
+
+    /**
+     * Long output format:
+     *
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" 
+     * "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool index&gt;"&gt;"
+     *
+     * @param verbose long/short format switch
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + index;
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        Constant c = cp.getConstant(index);
+        String str = cp.constantToString(c);
+        if (c instanceof ConstantClass) {
+            str = str.replace('.', '/');
+        }
+        return org.apache.tomcat.util.bcel.Constants.OPCODE_NAMES[opcode] + " " + str;
+    }
+
+
+    /**
+     * Read needed data (i.e., index) from file.
+     * @param bytes input stream
+     * @param wide wide prefix?
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        setIndex(bytes.readUnsignedShort());
+        length = 3;
+    }
+
+
+    /**
+     * @return index in constant pool referred by this instruction.
+     */
+    public final int getIndex() {
+        return index;
+    }
+
+
+    /**
+     * Set the index to constant pool.
+     * @param index in  constant pool.
+     */
+    public void setIndex( int index ) {
+        if (index < 0) {
+            throw new ClassGenException("Negative index value: " + index);
+        }
+        this.index = index;
+    }
+
+
+    /** @return type related with this instruction.
+     */
+    public Type getType( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        String name = cp.getConstantString(index, org.apache.tomcat.util.bcel.Constants.CONSTANT_Class);
+        if (!name.startsWith("[")) {
+            name = "L" + name + ";";
+        }
+        return Type.getType(name);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ClassElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/ClassElementValueGen.java
new file mode 100644 (file)
index 0000000..0910815
--- /dev/null
@@ -0,0 +1,80 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ClassElementValue;
+import org.apache.tomcat.util.bcel.generic.ConstantPoolGen;
+import org.apache.tomcat.util.bcel.generic.ObjectType;
+import org.apache.tomcat.util.bcel.generic.ElementValueGen;
+
+public class ClassElementValueGen extends ElementValueGen
+{
+       // For primitive types and string type, this points to the value entry in
+       // the cpool
+       // For 'class' this points to the class entry in the cpool
+       private int idx;
+
+       protected ClassElementValueGen(int typeIdx, ConstantPoolGen cpool)
+       {
+               super(ElementValueGen.CLASS, cpool);
+               this.idx = typeIdx;
+       }
+
+       public ClassElementValueGen(ObjectType t, ConstantPoolGen cpool)
+       {
+               super(ElementValueGen.CLASS, cpool);
+               // this.idx = cpool.addClass(t);
+               idx = cpool.addUtf8(t.getSignature());
+       }
+
+       /**
+        * Return immutable variant of this ClassElementValueGen
+        */
+       public ElementValue getElementValue()
+       {
+               return new ClassElementValue(type, idx, cpGen.getConstantPool());
+       }
+
+       public ClassElementValueGen(ClassElementValue value, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               super(CLASS, cpool);
+               if (copyPoolEntries)
+               {
+                       // idx = cpool.addClass(value.getClassString());
+                       idx = cpool.addUtf8(value.getClassString());
+               }
+               else
+               {
+                       idx = value.getIndex();
+               }
+       }
+
+       public int getIndex()
+       {
+               return idx;
+       }
+
+       public String getClassString()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx);
+               return cu8.getBytes();
+               // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx);
+               // ConstantUtf8 utf8 =
+               // (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex());
+               // return utf8.getBytes();
+       }
+
+       public String stringifyValue()
+       {
+               return getClassString();
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 kind of value
+               dos.writeShort(idx);
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ClassGen.java b/java/org/apache/tomcat/util/bcel/generic/ClassGen.java
new file mode 100644 (file)
index 0000000..e730ff9
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.AccessFlags;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.Annotations;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.Field;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.RuntimeInvisibleAnnotations;
+import org.apache.tomcat.util.bcel.classfile.RuntimeVisibleAnnotations;
+import org.apache.tomcat.util.bcel.classfile.SourceFile;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/** 
+ * Template class for building up a java class. May be initialized with an
+ * existing java class (file).
+ *
+ * @see JavaClass
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ClassGen extends AccessFlags implements Cloneable {
+
+    /* Corresponds to the fields found in a JavaClass object.
+     */
+    private String class_name, super_class_name, file_name;
+    private int class_name_index = -1, superclass_name_index = -1;
+    private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
+    private ConstantPoolGen cp; // Template for building up constant pool
+    // ArrayLists instead of arrays to gather fields, methods, etc.
+    private List field_vec = new ArrayList();
+    private List method_vec = new ArrayList();
+    private List attribute_vec = new ArrayList();
+    private List interface_vec = new ArrayList();
+    private List annotation_vec = new ArrayList();
+       
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            ClassGen THIS = (ClassGen) o1;
+            ClassGen THAT = (ClassGen) o2;
+            return THIS.getClassName().equals(THAT.getClassName());
+        }
+
+
+        public int hashCode( Object o ) {
+            ClassGen THIS = (ClassGen) o;
+            return THIS.getClassName().hashCode();
+        }
+    };
+
+
+    /** Convenience constructor to set up some important values initially.
+     *
+     * @param class_name fully qualified class name
+     * @param super_class_name fully qualified superclass name
+     * @param file_name source file name
+     * @param access_flags access qualifiers
+     * @param interfaces implemented interfaces
+     * @param cp constant pool to use
+     */
+    public ClassGen(String class_name, String super_class_name, String file_name, int access_flags,
+            String[] interfaces, ConstantPoolGen cp) {
+        this.class_name = class_name;
+        this.super_class_name = super_class_name;
+        this.file_name = file_name;
+        this.access_flags = access_flags;
+        this.cp = cp;
+        // Put everything needed by default into the constant pool and the vectors
+        if (file_name != null) {
+            addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp
+                    .getConstantPool()));
+        }
+        class_name_index = cp.addClass(class_name);
+        superclass_name_index = cp.addClass(super_class_name);
+        if (interfaces != null) {
+            for (int i = 0; i < interfaces.length; i++) {
+                addInterface(interfaces[i]);
+            }
+        }
+    }
+
+
+    /** Convenience constructor to set up some important values initially.
+     *
+     * @param class_name fully qualified class name
+     * @param super_class_name fully qualified superclass name
+     * @param file_name source file name
+     * @param access_flags access qualifiers
+     * @param interfaces implemented interfaces
+     */
+    public ClassGen(String class_name, String super_class_name, String file_name, int access_flags,
+            String[] interfaces) {
+        this(class_name, super_class_name, file_name, access_flags, interfaces,
+                new ConstantPoolGen());
+    }
+
+
+    /**
+     * Initialize with existing class.
+     * @param clazz JavaClass object (e.g. read from file)
+     */
+    public ClassGen(JavaClass clazz) {
+        class_name_index = clazz.getClassNameIndex();
+        superclass_name_index = clazz.getSuperclassNameIndex();
+        class_name = clazz.getClassName();
+        super_class_name = clazz.getSuperclassName();
+        file_name = clazz.getSourceFileName();
+        access_flags = clazz.getAccessFlags();
+        cp = new ConstantPoolGen(clazz.getConstantPool());
+        major = clazz.getMajor();
+        minor = clazz.getMinor();
+        Attribute[] attributes = clazz.getAttributes();
+        // J5TODO: Could make unpacking lazy, done on first reference
+        AnnotationEntryGen[] annotations = unpackAnnotations(attributes);
+        Method[] methods = clazz.getMethods();
+        Field[] fields = clazz.getFields();
+        String[] interfaces = clazz.getInterfaceNames();
+        for (int i = 0; i < interfaces.length; i++) {
+            addInterface(interfaces[i]);
+        }
+        for (int i = 0; i < attributes.length; i++) {
+               if (!(attributes[i] instanceof Annotations)) {
+                       addAttribute(attributes[i]);
+               }
+        }
+        for(int i=0; i < annotations.length; i++) {
+            addAnnotationEntry(annotations[i]);
+        }
+        for (int i = 0; i < methods.length; i++) {
+            addMethod(methods[i]);
+        }
+        for (int i = 0; i < fields.length; i++) {
+            addField(fields[i]);
+        }
+    }
+    
+    /**
+        * Look for attributes representing annotations and unpack them.
+        */
+       private AnnotationEntryGen[] unpackAnnotations(Attribute[] attrs)
+       {
+               List /* AnnotationGen */annotationGenObjs = new ArrayList();
+               for (int i = 0; i < attrs.length; i++)
+               {
+                       Attribute attr = attrs[i];
+                       if (attr instanceof RuntimeVisibleAnnotations)
+                       {
+                               RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr;
+                               AnnotationEntry[] annos = rva.getAnnotationEntries();
+                               for (int j = 0; j < annos.length; j++)
+                               {
+                                       AnnotationEntry a = annos[j];
+                                       annotationGenObjs.add(new AnnotationEntryGen(a,
+                                                       getConstantPool(), false));
+                               }
+                       }
+                       else
+                               if (attr instanceof RuntimeInvisibleAnnotations)
+                               {
+                                       RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
+                                       AnnotationEntry[] annos = ria.getAnnotationEntries();
+                                       for (int j = 0; j < annos.length; j++)
+                                       {
+                                               AnnotationEntry a = annos[j];
+                                               annotationGenObjs.add(new AnnotationEntryGen(a,
+                                                               getConstantPool(), false));
+                                       }
+                               }
+               }
+               return (AnnotationEntryGen[]) annotationGenObjs
+                               .toArray(new AnnotationEntryGen[annotationGenObjs.size()]);
+       }
+
+
+    /**
+     * @return the (finally) built up Java class object.
+     */
+    public JavaClass getJavaClass() {
+        int[] interfaces = getInterfaces();
+        Field[] fields = getFields();
+        Method[] methods = getMethods();
+        Attribute[] attributes = null;
+        if (annotation_vec.isEmpty()) {
+               attributes = getAttributes();
+        } else {
+               // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
+            Attribute[] annAttributes  = Utility.getAnnotationAttributes(cp,annotation_vec);
+            attributes = new Attribute[attribute_vec.size()+annAttributes.length];
+            attribute_vec.toArray(attributes);
+            System.arraycopy(annAttributes,0,attributes,attribute_vec.size(),annAttributes.length);       
+        }
+        // Must be last since the above calls may still add something to it
+        ConstantPool _cp = this.cp.getFinalConstantPool();
+        return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor,
+                access_flags, _cp, interfaces, fields, methods, attributes);
+    }
+
+
+    /**
+     * Add an interface to this class, i.e., this class has to implement it.
+     * @param name interface to implement (fully qualified class name)
+     */
+    public void addInterface( String name ) {
+        interface_vec.add(name);
+    }
+
+
+    /**
+     * Remove an interface from this class.
+     * @param name interface to remove (fully qualified name)
+     */
+    public void removeInterface( String name ) {
+        interface_vec.remove(name);
+    }
+
+
+    /**
+     * @return major version number of class file
+     */
+    public int getMajor() {
+        return major;
+    }
+
+
+    /** Set major version number of class file, default value is 45 (JDK 1.1)
+     * @param major major version number
+     */
+    public void setMajor( int major ) {
+        this.major = major;
+    }
+
+
+    /** Set minor version number of class file, default value is 3 (JDK 1.1)
+     * @param minor minor version number
+     */
+    public void setMinor( int minor ) {
+        this.minor = minor;
+    }
+
+
+    /**
+     * @return minor version number of class file
+     */
+    public int getMinor() {
+        return minor;
+    }
+
+
+    /**
+     * Add an attribute to this class.
+     * @param a attribute to add
+     */
+    public void addAttribute( Attribute a ) {
+        attribute_vec.add(a);
+    }
+    
+    public void addAnnotationEntry(AnnotationEntryGen a) { 
+       annotation_vec.add(a); 
+    }
+
+
+    /**
+     * Add a method to this class.
+     * @param m method to add
+     */
+    public void addMethod( Method m ) {
+        method_vec.add(m);
+    }
+
+
+    /**
+     * Convenience method.
+     *
+     * Add an empty constructor to this class that does nothing but calling super().
+     * @param access_flags rights for constructor
+     */
+    public void addEmptyConstructor( int access_flags ) {
+        InstructionList il = new InstructionList();
+        il.append(InstructionConstants.THIS); // Push `this'
+        il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
+        il.append(InstructionConstants.RETURN);
+        MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>",
+                class_name, il, cp);
+        mg.setMaxStack(1);
+        addMethod(mg.getMethod());
+    }
+
+
+    /**
+     * Add a field to this class.
+     * @param f field to add
+     */
+    public void addField( Field f ) {
+        field_vec.add(f);
+    }
+
+
+    public boolean containsField( Field f ) {
+        return field_vec.contains(f);
+    }
+
+
+    /** @return field object with given name, or null
+     */
+    public Field containsField( String name ) {
+        for (Iterator e = field_vec.iterator(); e.hasNext();) {
+            Field f = (Field) e.next();
+            if (f.getName().equals(name)) {
+                return f;
+            }
+        }
+        return null;
+    }
+
+
+    /** @return method object with given name and signature, or null
+     */
+    public Method containsMethod( String name, String signature ) {
+        for (Iterator e = method_vec.iterator(); e.hasNext();) {
+            Method m = (Method) e.next();
+            if (m.getName().equals(name) && m.getSignature().equals(signature)) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Remove an attribute from this class.
+     * @param a attribute to remove
+     */
+    public void removeAttribute( Attribute a ) {
+        attribute_vec.remove(a);
+    }
+
+
+    /**
+     * Remove a method from this class.
+     * @param m method to remove
+     */
+    public void removeMethod( Method m ) {
+        method_vec.remove(m);
+    }
+
+
+    /** Replace given method with new one. If the old one does not exist
+     * add the new_ method to the class anyway.
+     */
+    public void replaceMethod( Method old, Method new_ ) {
+        if (new_ == null) {
+            throw new ClassGenException("Replacement method must not be null");
+        }
+        int i = method_vec.indexOf(old);
+        if (i < 0) {
+            method_vec.add(new_);
+        } else {
+            method_vec.set(i, new_);
+        }
+    }
+
+
+    /** Replace given field with new one. If the old one does not exist
+     * add the new_ field to the class anyway.
+     */
+    public void replaceField( Field old, Field new_ ) {
+        if (new_ == null) {
+            throw new ClassGenException("Replacement method must not be null");
+        }
+        int i = field_vec.indexOf(old);
+        if (i < 0) {
+            field_vec.add(new_);
+        } else {
+            field_vec.set(i, new_);
+        }
+    }
+
+
+    /**
+     * Remove a field to this class.
+     * @param f field to remove
+     */
+    public void removeField( Field f ) {
+        field_vec.remove(f);
+    }
+
+
+    public String getClassName() {
+        return class_name;
+    }
+
+
+    public String getSuperclassName() {
+        return super_class_name;
+    }
+
+
+    public String getFileName() {
+        return file_name;
+    }
+
+
+    public void setClassName( String name ) {
+        class_name = name.replace('/', '.');
+        class_name_index = cp.addClass(name);
+    }
+
+
+    public void setSuperclassName( String name ) {
+        super_class_name = name.replace('/', '.');
+        superclass_name_index = cp.addClass(name);
+    }
+
+
+    public Method[] getMethods() {
+        return (Method[]) method_vec.toArray(new Method[method_vec.size()]);
+    }
+
+
+    public void setMethods( Method[] methods ) {
+        method_vec.clear();
+        for (int m = 0; m < methods.length; m++) {
+            addMethod(methods[m]);
+        }
+    }
+
+
+    public void setMethodAt( Method method, int pos ) {
+        method_vec.set(pos, method);
+    }
+
+
+    public Method getMethodAt( int pos ) {
+        return (Method) method_vec.get(pos);
+    }
+
+
+    public String[] getInterfaceNames() {
+        int size = interface_vec.size();
+        String[] interfaces = new String[size];
+        interface_vec.toArray(interfaces);
+        return interfaces;
+    }
+
+
+    public int[] getInterfaces() {
+        int size = interface_vec.size();
+        int[] interfaces = new int[size];
+        for (int i = 0; i < size; i++) {
+            interfaces[i] = cp.addClass((String) interface_vec.get(i));
+        }
+        return interfaces;
+    }
+
+
+    public Field[] getFields() {
+        return (Field[]) field_vec.toArray(new Field[field_vec.size()]);
+    }
+
+
+    public Attribute[] getAttributes() {
+        return (Attribute[]) attribute_vec.toArray(new Attribute[attribute_vec.size()]);
+    }
+    
+    //  J5TODO: Should we make calling unpackAnnotations() lazy and put it in here?
+    public AnnotationEntryGen[] getAnnotationEntries() {
+       return (AnnotationEntryGen[]) annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]);
+    }
+
+
+    public ConstantPoolGen getConstantPool() {
+        return cp;
+    }
+
+
+    public void setConstantPool( ConstantPoolGen constant_pool ) {
+        cp = constant_pool;
+    }
+
+
+    public void setClassNameIndex( int class_name_index ) {
+        this.class_name_index = class_name_index;
+        class_name = cp.getConstantPool().getConstantString(class_name_index,
+                Constants.CONSTANT_Class).replace('/', '.');
+    }
+
+
+    public void setSuperclassNameIndex( int superclass_name_index ) {
+        this.superclass_name_index = superclass_name_index;
+        super_class_name = cp.getConstantPool().getConstantString(superclass_name_index,
+                Constants.CONSTANT_Class).replace('/', '.');
+    }
+
+
+    public int getSuperclassNameIndex() {
+        return superclass_name_index;
+    }
+
+
+    public int getClassNameIndex() {
+        return class_name_index;
+    }
+
+    private ArrayList observers;
+
+
+    /** Add observer for this object.
+     */
+    public void addObserver( ClassObserver o ) {
+        if (observers == null) {
+            observers = new ArrayList();
+        }
+        observers.add(o);
+    }
+
+
+    /** Remove observer for this object.
+     */
+    public void removeObserver( ClassObserver o ) {
+        if (observers != null) {
+            observers.remove(o);
+        }
+    }
+
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
+     */
+    public void update() {
+        if (observers != null) {
+            for (Iterator e = observers.iterator(); e.hasNext();) {
+                ((ClassObserver) e.next()).notify(this);
+            }
+        }
+    }
+
+
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            System.err.println(e);
+            return null;
+        }
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two ClassGen objects are said to be equal when
+     * their class names are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the class name.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ClassGenException.java b/java/org/apache/tomcat/util/bcel/generic/ClassGenException.java
new file mode 100644 (file)
index 0000000..d478259
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared
+ * in the throws clause every time.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ClassGenException extends RuntimeException {
+
+    public ClassGenException() {
+        super();
+    }
+
+
+    public ClassGenException(String s) {
+        super(s);
+    }
+    
+    public ClassGenException(String s, Throwable initCause) {
+       super(s, initCause);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ClassObserver.java b/java/org/apache/tomcat/util/bcel/generic/ClassObserver.java
new file mode 100644 (file)
index 0000000..591bbd9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Implement this interface if you're interested in changes to a ClassGen object
+ * and register yourself with addObserver().
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface ClassObserver {
+
+    public void notify( ClassGen clazz );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CodeExceptionGen.java b/java/org/apache/tomcat/util/bcel/generic/CodeExceptionGen.java
new file mode 100644 (file)
index 0000000..fbb466e
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.classfile.CodeException;
+
+/** 
+ * This class represents an exception handler, i.e., specifies the  region where
+ * a handler is active and an instruction where the actual handling is done.
+ * pool as parameters. Opposed to the JVM specification the end of the handled
+ * region is set to be inclusive, i.e. all instructions between start and end
+ * are protected including the start and end instructions (handles) themselves.
+ * The end of the region is automatically mapped to be exclusive when calling
+ * getCodeException(), i.e., there is no difference semantically.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     MethodGen
+ * @see     CodeException
+ * @see     InstructionHandle
+ */
+public final class CodeExceptionGen implements InstructionTargeter, Cloneable, java.io.Serializable {
+
+    private InstructionHandle start_pc;
+    private InstructionHandle end_pc;
+    private InstructionHandle handler_pc;
+    private ObjectType catch_type;
+
+
+    /**
+     * Add an exception handler, i.e., specify region where a handler is active and an
+     * instruction where the actual handling is done.
+     *
+     * @param start_pc Start of handled region (inclusive)
+     * @param end_pc End of handled region (inclusive)
+     * @param handler_pc Where handling is done
+     * @param catch_type which exception is handled, null for ANY
+     */
+    public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc,
+            InstructionHandle handler_pc, ObjectType catch_type) {
+        setStartPC(start_pc);
+        setEndPC(end_pc);
+        setHandlerPC(handler_pc);
+        this.catch_type = catch_type;
+    }
+
+
+    /**
+     * Get CodeException object.<BR>
+     *
+     * This relies on that the instruction list has already been dumped
+     * to byte code or or that the `setPositions' methods has been
+     * called for the instruction list.
+     *
+     * @param cp constant pool
+     */
+    public CodeException getCodeException( ConstantPoolGen cp ) {
+        return new CodeException(start_pc.getPosition(), end_pc.getPosition()
+                + end_pc.getInstruction().getLength(), handler_pc.getPosition(),
+                (catch_type == null) ? 0 : cp.addClass(catch_type));
+    }
+
+
+    /* Set start of handler 
+     * @param start_pc Start of handled region (inclusive)
+     */
+    public void setStartPC( InstructionHandle start_pc ) {
+        BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
+        this.start_pc = start_pc;
+    }
+
+
+    /* Set end of handler 
+     * @param end_pc End of handled region (inclusive)
+     */
+    public void setEndPC( InstructionHandle end_pc ) {
+        BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
+        this.end_pc = end_pc;
+    }
+
+
+    /* Set handler code
+     * @param handler_pc Start of handler
+     */
+    public void setHandlerPC( InstructionHandle handler_pc ) {
+        BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
+        this.handler_pc = handler_pc;
+    }
+
+
+    /**
+     * @param old_ih old target, either start or end
+     * @param new_ih new target
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        boolean targeted = false;
+        if (start_pc == old_ih) {
+            targeted = true;
+            setStartPC(new_ih);
+        }
+        if (end_pc == old_ih) {
+            targeted = true;
+            setEndPC(new_ih);
+        }
+        if (handler_pc == old_ih) {
+            targeted = true;
+            setHandlerPC(new_ih);
+        }
+        if (!targeted) {
+            throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", "
+                    + end_pc + ", " + handler_pc + "}");
+        }
+    }
+
+
+    /**
+     * @return true, if ih is target of this handler
+     */
+    public boolean containsTarget( InstructionHandle ih ) {
+        return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
+    }
+
+
+    /** Sets the type of the Exception to catch. Set 'null' for ANY. */
+    public void setCatchType( ObjectType catch_type ) {
+        this.catch_type = catch_type;
+    }
+
+
+    /** Gets the type of the Exception to catch, 'null' for ANY. */
+    public ObjectType getCatchType() {
+        return catch_type;
+    }
+
+
+    /** @return start of handled region (inclusive)
+     */
+    public InstructionHandle getStartPC() {
+        return start_pc;
+    }
+
+
+    /** @return end of handled region (inclusive)
+     */
+    public InstructionHandle getEndPC() {
+        return end_pc;
+    }
+
+
+    /** @return start of handler
+     */
+    public InstructionHandle getHandlerPC() {
+        return handler_pc;
+    }
+
+
+    public String toString() {
+        return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
+    }
+
+
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            System.err.println(e);
+            return null;
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/CompoundInstruction.java b/java/org/apache/tomcat/util/bcel/generic/CompoundInstruction.java
new file mode 100644 (file)
index 0000000..698745f
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Wrapper class for `compound' operations, virtual instructions that
+ * don't exist as byte code, but give a useful meaning. For example,
+ * the (virtual) PUSH instruction takes an arbitray argument and produces the
+ * appropiate code at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the
+ * SWITCH instruction as a useful template for either LOOKUPSWITCH or
+ * TABLESWITCH.
+ *
+ * The interface provides the possibilty for the user to write
+ * `templates' or `macros' for such reuseable code patterns.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see PUSH
+ * @see SWITCH
+ */
+public interface CompoundInstruction {
+
+    public InstructionList getInstructionList();
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ConstantPoolGen.java b/java/org/apache/tomcat/util/bcel/generic/ConstantPoolGen.java
new file mode 100644 (file)
index 0000000..676794c
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.classfile.ConstantCP;
+import org.apache.tomcat.util.bcel.classfile.ConstantClass;
+import org.apache.tomcat.util.bcel.classfile.ConstantDouble;
+import org.apache.tomcat.util.bcel.classfile.ConstantFieldref;
+import org.apache.tomcat.util.bcel.classfile.ConstantFloat;
+import org.apache.tomcat.util.bcel.classfile.ConstantInteger;
+import org.apache.tomcat.util.bcel.classfile.ConstantInterfaceMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantLong;
+import org.apache.tomcat.util.bcel.classfile.ConstantMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantNameAndType;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantString;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+
+/** 
+ * This class is used to build up a constant pool. The user adds
+ * constants via `addXXX' methods, `addString', `addClass',
+ * etc.. These methods return an index into the constant
+ * pool. Finally, `getFinalConstantPool()' returns the constant pool
+ * built up. Intermediate versions of the constant pool can be
+ * obtained with `getConstantPool()'. A constant pool has capacity for
+ * Constants.MAX_SHORT entries. Note that the first (0) is used by the
+ * JVM and that Double and Long constants need two slots.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Constant
+ */
+public class ConstantPoolGen implements java.io.Serializable {
+
+    protected int size; 
+    protected Constant[] constants;
+    protected int index = 1; // First entry (0) used by JVM
+    private static final String METHODREF_DELIM = ":";
+    private static final String IMETHODREF_DELIM = "#";
+    private static final String FIELDREF_DELIM = "&";
+    private static final String NAT_DELIM = "%";
+
+    private static class Index implements java.io.Serializable {
+
+        int index;
+
+
+        Index(int i) {
+            index = i;
+        }
+    }
+
+
+    /**
+     * Initialize with given array of constants.
+     *
+     * @param cs array of given constants, new ones will be appended
+     */
+    public ConstantPoolGen(Constant[] cs) {
+       StringBuffer sb = new StringBuffer(256);
+        
+        size = Math.max(256, cs.length + 64);
+        constants = new Constant[size];
+        
+        System.arraycopy(cs, 0, constants, 0, cs.length);
+        if (cs.length > 0) {
+            index = cs.length;
+        }
+       
+       
+        for (int i = 1; i < index; i++) {
+            Constant c = constants[i];
+            if (c instanceof ConstantString) {
+                ConstantString s = (ConstantString) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
+                String key = u8.getBytes();
+                if (!string_table.containsKey(key)) {
+                    string_table.put(key, new Index(i));
+                }
+            } else if (c instanceof ConstantClass) {
+                ConstantClass s = (ConstantClass) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
+                String key = u8.getBytes();
+                if (!class_table.containsKey(key)) {
+                    class_table.put(key, new Index(i));
+                }
+            } else if (c instanceof ConstantNameAndType) {
+                ConstantNameAndType n = (ConstantNameAndType) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
+                ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
+                
+                sb.append(u8.getBytes());
+                sb.append(NAT_DELIM);
+                sb.append(u8_2.getBytes());
+                String key = sb.toString();
+                sb.delete(0, sb.length());
+                
+                if (!n_a_t_table.containsKey(key)) {
+                    n_a_t_table.put(key, new Index(i));
+                }
+            } else if (c instanceof ConstantUtf8) {
+                ConstantUtf8 u = (ConstantUtf8) c;
+                String key = u.getBytes();
+                if (!utf8_table.containsKey(key)) {
+                    utf8_table.put(key, new Index(i));
+                }
+            } else if (c instanceof ConstantCP) {
+                ConstantCP m = (ConstantCP) c;
+                ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
+                ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
+                ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
+                String class_name = u8.getBytes().replace('/', '.');
+                u8 = (ConstantUtf8) constants[n.getNameIndex()];
+                String method_name = u8.getBytes();
+                u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
+                String signature = u8.getBytes();
+                String delim = METHODREF_DELIM;
+                if (c instanceof ConstantInterfaceMethodref) {
+                    delim = IMETHODREF_DELIM;
+                } else if (c instanceof ConstantFieldref) {
+                    delim = FIELDREF_DELIM;
+                }
+                
+                sb.append(class_name);
+                sb.append(delim);
+                sb.append(method_name);
+                sb.append(delim);
+                sb.append(signature);
+                String key = sb.toString();
+                sb.delete(0, sb.length());
+                
+                if (!cp_table.containsKey(key)) {
+                    cp_table.put(key, new Index(i));
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Initialize with given constant pool.
+     */
+    public ConstantPoolGen(ConstantPool cp) {
+        this(cp.getConstantPool());
+    }
+
+
+    /**
+     * Create empty constant pool.
+     */
+    public ConstantPoolGen() {
+       size = 256;
+        constants = new Constant[size];
+    }
+
+
+    /** Resize internal array of constants.
+     */
+    protected void adjustSize() {
+        if (index + 3 >= size) {
+            Constant[] cs = constants;
+            size *= 2;
+            constants = new Constant[size];
+            System.arraycopy(cs, 0, constants, 0, index);
+        }
+    }
+
+    private Map string_table = new HashMap();
+
+
+    /** 
+     * Look for ConstantString in ConstantPool containing String `str'.
+     *
+     * @param str String to search for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupString( String str ) {
+        Index index = (Index) string_table.get(str);
+        return (index != null) ? index.index : -1;
+    }
+
+
+    /**
+     * Add a new String constant to the ConstantPool, if it is not already in there.
+     *
+     * @param str String to add
+     * @return index of entry
+     */
+    public int addString( String str ) {
+        int ret;
+        if ((ret = lookupString(str)) != -1) {
+            return ret; // Already in CP
+        }
+        int utf8 = addUtf8(str);
+        adjustSize();
+        ConstantString s = new ConstantString(utf8);
+        ret = index;
+        constants[index++] = s;
+        if (!string_table.containsKey(str)) {
+            string_table.put(str, new Index(ret));
+        }
+        return ret;
+    }
+
+    private Map class_table = new HashMap();
+
+
+    /**
+     * Look for ConstantClass in ConstantPool named `str'.
+     *
+     * @param str String to search for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupClass( String str ) {
+        Index index = (Index) class_table.get(str.replace('.', '/'));
+        return (index != null) ? index.index : -1;
+    }
+
+
+    private int addClass_( String clazz ) {
+        int ret;
+        if ((ret = lookupClass(clazz)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ConstantClass c = new ConstantClass(addUtf8(clazz));
+        ret = index;
+        constants[index++] = c;
+        if (!class_table.containsKey(clazz)) {
+            class_table.put(clazz, new Index(ret));
+        }
+        return ret;
+    }
+
+
+    /**
+     * Add a new Class reference to the ConstantPool, if it is not already in there.
+     *
+     * @param str Class to add
+     * @return index of entry
+     */
+    public int addClass( String str ) {
+        return addClass_(str.replace('.', '/'));
+    }
+
+
+    /**
+     * Add a new Class reference to the ConstantPool for a given type.
+     *
+     * @param type Class to add
+     * @return index of entry
+     */
+    public int addClass( ObjectType type ) {
+        return addClass(type.getClassName());
+    }
+
+
+    /**
+     * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
+     * instruction, e.g. to the ConstantPool.
+     *
+     * @param type type of array class
+     * @return index of entry
+     */
+    public int addArrayClass( ArrayType type ) {
+        return addClass_(type.getSignature());
+    }
+
+
+    /** 
+     * Look for ConstantInteger in ConstantPool.
+     *
+     * @param n integer number to look for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupInteger( int n ) {
+        for (int i = 1; i < index; i++) {
+            if (constants[i] instanceof ConstantInteger) {
+                ConstantInteger c = (ConstantInteger) constants[i];
+                if (c.getBytes() == n) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Add a new Integer constant to the ConstantPool, if it is not already in there.
+     *
+     * @param n integer number to add
+     * @return index of entry
+     */
+    public int addInteger( int n ) {
+        int ret;
+        if ((ret = lookupInteger(n)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ret = index;
+        constants[index++] = new ConstantInteger(n);
+        return ret;
+    }
+
+
+    /** 
+     * Look for ConstantFloat in ConstantPool.
+     *
+     * @param n Float number to look for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupFloat( float n ) {
+        int bits = Float.floatToIntBits(n);
+        for (int i = 1; i < index; i++) {
+            if (constants[i] instanceof ConstantFloat) {
+                ConstantFloat c = (ConstantFloat) constants[i];
+                if (Float.floatToIntBits(c.getBytes()) == bits) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Add a new Float constant to the ConstantPool, if it is not already in there.
+     *
+     * @param n Float number to add
+     * @return index of entry
+     */
+    public int addFloat( float n ) {
+        int ret;
+        if ((ret = lookupFloat(n)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ret = index;
+        constants[index++] = new ConstantFloat(n);
+        return ret;
+    }
+
+    private Map utf8_table = new HashMap();
+
+
+    /** 
+     * Look for ConstantUtf8 in ConstantPool.
+     *
+     * @param n Utf8 string to look for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupUtf8( String n ) {
+        Index index = (Index) utf8_table.get(n);
+        return (index != null) ? index.index : -1;
+    }
+
+
+    /**
+     * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
+     *
+     * @param n Utf8 string to add
+     * @return index of entry
+     */
+    public int addUtf8( String n ) {
+        int ret;
+        if ((ret = lookupUtf8(n)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ret = index;
+        constants[index++] = new ConstantUtf8(n);
+        if (!utf8_table.containsKey(n)) {
+            utf8_table.put(n, new Index(ret));
+        }
+        return ret;
+    }
+
+
+    /** 
+     * Look for ConstantLong in ConstantPool.
+     *
+     * @param n Long number to look for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupLong( long n ) {
+        for (int i = 1; i < index; i++) {
+            if (constants[i] instanceof ConstantLong) {
+                ConstantLong c = (ConstantLong) constants[i];
+                if (c.getBytes() == n) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Add a new long constant to the ConstantPool, if it is not already in there.
+     *
+     * @param n Long number to add
+     * @return index of entry
+     */
+    public int addLong( long n ) {
+        int ret;
+        if ((ret = lookupLong(n)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ret = index;
+        constants[index] = new ConstantLong(n);
+        index += 2; // Wastes one entry according to spec
+        return ret;
+    }
+
+
+    /** 
+     * Look for ConstantDouble in ConstantPool.
+     *
+     * @param n Double number to look for
+     * @return index on success, -1 otherwise
+     */
+    public int lookupDouble( double n ) {
+        long bits = Double.doubleToLongBits(n);
+        for (int i = 1; i < index; i++) {
+            if (constants[i] instanceof ConstantDouble) {
+                ConstantDouble c = (ConstantDouble) constants[i];
+                if (Double.doubleToLongBits(c.getBytes()) == bits) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Add a new double constant to the ConstantPool, if it is not already in there.
+     *
+     * @param n Double number to add
+     * @return index of entry
+     */
+    public int addDouble( double n ) {
+        int ret;
+        if ((ret = lookupDouble(n)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        ret = index;
+        constants[index] = new ConstantDouble(n);
+        index += 2; // Wastes one entry according to spec
+        return ret;
+    }
+
+    private Map n_a_t_table = new HashMap();
+
+
+    /** 
+     * Look for ConstantNameAndType in ConstantPool.
+     *
+     * @param name of variable/method
+     * @param signature of variable/method
+     * @return index on success, -1 otherwise
+     */
+    public int lookupNameAndType( String name, String signature ) {
+        Index _index = (Index) n_a_t_table.get(name + NAT_DELIM + signature);
+        return (_index != null) ? _index.index : -1;
+    }
+
+
+    /**
+     * Add a new NameAndType constant to the ConstantPool if it is not already 
+     * in there.
+     *
+     * @param name Name string to add
+     * @param signature signature string to add
+     * @return index of entry
+     */
+    public int addNameAndType( String name, String signature ) {
+        int ret;
+        int name_index, signature_index;
+        if ((ret = lookupNameAndType(name, signature)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        name_index = addUtf8(name);
+        signature_index = addUtf8(signature);
+        ret = index;
+        constants[index++] = new ConstantNameAndType(name_index, signature_index);
+        String key = name + NAT_DELIM + signature;
+        if (!n_a_t_table.containsKey(key)) {
+            n_a_t_table.put(key, new Index(ret));
+        }
+        return ret;
+    }
+
+    private Map cp_table = new HashMap();
+
+
+    /** 
+     * Look for ConstantMethodref in ConstantPool.
+     *
+     * @param class_name Where to find method
+     * @param method_name Guess what
+     * @param signature return and argument types
+     * @return index on success, -1 otherwise
+     */
+    public int lookupMethodref( String class_name, String method_name, String signature ) {
+        Index index = (Index) cp_table.get(class_name + METHODREF_DELIM + method_name
+                + METHODREF_DELIM + signature);
+        return (index != null) ? index.index : -1;
+    }
+
+
+    public int lookupMethodref( MethodGen method ) {
+        return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
+    }
+
+
+    /**
+     * Add a new Methodref constant to the ConstantPool, if it is not already 
+     * in there.
+     *
+     * @param class_name class name string to add
+     * @param method_name method name string to add
+     * @param signature method signature string to add
+     * @return index of entry
+     */
+    public int addMethodref( String class_name, String method_name, String signature ) {
+        int ret, class_index, name_and_type_index;
+        if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        name_and_type_index = addNameAndType(method_name, signature);
+        class_index = addClass(class_name);
+        ret = index;
+        constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
+        String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature;
+        if (!cp_table.containsKey(key)) {
+            cp_table.put(key, new Index(ret));
+        }
+        return ret;
+    }
+
+
+    public int addMethodref( MethodGen method ) {
+        return addMethodref(method.getClassName(), method.getName(), method.getSignature());
+    }
+
+
+    /** 
+     * Look for ConstantInterfaceMethodref in ConstantPool.
+     *
+     * @param class_name Where to find method
+     * @param method_name Guess what
+     * @param signature return and argument types
+     * @return index on success, -1 otherwise
+     */
+    public int lookupInterfaceMethodref( String class_name, String method_name, String signature ) {
+        Index index = (Index) cp_table.get(class_name + IMETHODREF_DELIM + method_name
+                + IMETHODREF_DELIM + signature);
+        return (index != null) ? index.index : -1;
+    }
+
+
+    public int lookupInterfaceMethodref( MethodGen method ) {
+        return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
+                .getSignature());
+    }
+
+
+    /**
+     * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already 
+     * in there.
+     *
+     * @param class_name class name string to add
+     * @param method_name method name string to add
+     * @param signature signature string to add
+     * @return index of entry
+     */
+    public int addInterfaceMethodref( String class_name, String method_name, String signature ) {
+        int ret, class_index, name_and_type_index;
+        if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        class_index = addClass(class_name);
+        name_and_type_index = addNameAndType(method_name, signature);
+        ret = index;
+        constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
+        String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature;
+        if (!cp_table.containsKey(key)) {
+            cp_table.put(key, new Index(ret));
+        }
+        return ret;
+    }
+
+
+    public int addInterfaceMethodref( MethodGen method ) {
+        return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
+    }
+
+
+    /** 
+     * Look for ConstantFieldref in ConstantPool.
+     *
+     * @param class_name Where to find method
+     * @param field_name Guess what
+     * @param signature return and argument types
+     * @return index on success, -1 otherwise
+     */
+    public int lookupFieldref( String class_name, String field_name, String signature ) {
+        Index index = (Index) cp_table.get(class_name + FIELDREF_DELIM + field_name
+                + FIELDREF_DELIM + signature);
+        return (index != null) ? index.index : -1;
+    }
+
+
+    /**
+     * Add a new Fieldref constant to the ConstantPool, if it is not already 
+     * in there.
+     *
+     * @param class_name class name string to add
+     * @param field_name field name string to add
+     * @param signature signature string to add
+     * @return index of entry
+     */
+    public int addFieldref( String class_name, String field_name, String signature ) {
+        int ret;
+        int class_index, name_and_type_index;
+        if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) {
+            return ret; // Already in CP
+        }
+        adjustSize();
+        class_index = addClass(class_name);
+        name_and_type_index = addNameAndType(field_name, signature);
+        ret = index;
+        constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
+        String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature;
+        if (!cp_table.containsKey(key)) {
+            cp_table.put(key, new Index(ret));
+        }
+        return ret;
+    }
+
+
+    /**
+     * @param i index in constant pool
+     * @return constant pool entry at index i
+     */
+    public Constant getConstant( int i ) {
+        return constants[i];
+    }
+
+
+    /**
+     * Use with care!
+     *
+     * @param i index in constant pool
+     * @param c new constant pool entry at index i
+     */
+    public void setConstant( int i, Constant c ) {
+        constants[i] = c;
+    }
+
+
+    /**
+     * @return intermediate constant pool
+     */
+    public ConstantPool getConstantPool() {
+        return new ConstantPool(constants);
+    }
+
+
+    /**
+     * @return current size of constant pool
+     */
+    public int getSize() {
+        return index;
+    }
+
+
+    /**
+     * @return constant pool with proper length
+     */
+    public ConstantPool getFinalConstantPool() {
+        Constant[] cs = new Constant[index];
+        System.arraycopy(constants, 0, cs, 0, index);
+        return new ConstantPool(cs);
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 1; i < index; i++) {
+            buf.append(i).append(")").append(constants[i]).append("\n");
+        }
+        return buf.toString();
+    }
+
+
+    /** Import constant from another ConstantPool and return new index.
+     */
+    public int addConstant( Constant c, ConstantPoolGen cp ) {
+        Constant[] constants = cp.getConstantPool().getConstantPool();
+        switch (c.getTag()) {
+            case Constants.CONSTANT_String: {
+                ConstantString s = (ConstantString) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
+                return addString(u8.getBytes());
+            }
+            case Constants.CONSTANT_Class: {
+                ConstantClass s = (ConstantClass) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
+                return addClass(u8.getBytes());
+            }
+            case Constants.CONSTANT_NameAndType: {
+                ConstantNameAndType n = (ConstantNameAndType) c;
+                ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
+                ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
+                return addNameAndType(u8.getBytes(), u8_2.getBytes());
+            }
+            case Constants.CONSTANT_Utf8:
+                return addUtf8(((ConstantUtf8) c).getBytes());
+            case Constants.CONSTANT_Double:
+                return addDouble(((ConstantDouble) c).getBytes());
+            case Constants.CONSTANT_Float:
+                return addFloat(((ConstantFloat) c).getBytes());
+            case Constants.CONSTANT_Long:
+                return addLong(((ConstantLong) c).getBytes());
+            case Constants.CONSTANT_Integer:
+                return addInteger(((ConstantInteger) c).getBytes());
+            case Constants.CONSTANT_InterfaceMethodref:
+            case Constants.CONSTANT_Methodref:
+            case Constants.CONSTANT_Fieldref: {
+                ConstantCP m = (ConstantCP) c;
+                ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
+                ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
+                ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
+                String class_name = u8.getBytes().replace('/', '.');
+                u8 = (ConstantUtf8) constants[n.getNameIndex()];
+                String name = u8.getBytes();
+                u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
+                String signature = u8.getBytes();
+                switch (c.getTag()) {
+                    case Constants.CONSTANT_InterfaceMethodref:
+                        return addInterfaceMethodref(class_name, name, signature);
+                    case Constants.CONSTANT_Methodref:
+                        return addMethodref(class_name, name, signature);
+                    case Constants.CONSTANT_Fieldref:
+                        return addFieldref(class_name, name, signature);
+                    default: // Never reached
+                        throw new RuntimeException("Unknown constant type " + c);
+                }
+            }
+            default: // Never reached
+                throw new RuntimeException("Unknown constant type " + c);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ConstantPushInstruction.java b/java/org/apache/tomcat/util/bcel/generic/ConstantPushInstruction.java
new file mode 100644 (file)
index 0000000..7ff35a7
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes a push instruction that produces a literal on the stack
+ * such as  SIPUSH, BIPUSH, ICONST, etc.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+
+ * @see ICONST
+ * @see SIPUSH
+ */
+public interface ConstantPushInstruction extends PushInstruction, TypedInstruction {
+
+    public Number getValue();
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ConversionInstruction.java b/java/org/apache/tomcat/util/bcel/generic/ConversionInstruction.java
new file mode 100644 (file)
index 0000000..f17b6e0
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/**
+ * Super class for the x2y family of instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class ConversionInstruction extends Instruction implements TypedInstruction,
+        StackProducer, StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ConversionInstruction() {
+    }
+
+
+    /**
+     * @param opcode opcode of instruction
+     */
+    protected ConversionInstruction(short opcode) {
+        super(opcode, (short) 1);
+    }
+
+
+    /** @return type associated with the instruction
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        switch (opcode) {
+            case Constants.D2I:
+            case Constants.F2I:
+            case Constants.L2I:
+                return Type.INT;
+            case Constants.D2F:
+            case Constants.I2F:
+            case Constants.L2F:
+                return Type.FLOAT;
+            case Constants.D2L:
+            case Constants.F2L:
+            case Constants.I2L:
+                return Type.LONG;
+            case Constants.F2D:
+            case Constants.I2D:
+            case Constants.L2D:
+                return Type.DOUBLE;
+            case Constants.I2B:
+                return Type.BYTE;
+            case Constants.I2C:
+                return Type.CHAR;
+            case Constants.I2S:
+                return Type.SHORT;
+            default: // Never reached
+                throw new ClassGenException("Unknown type " + opcode);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/D2F.java b/java/org/apache/tomcat/util/bcel/generic/D2F.java
new file mode 100644 (file)
index 0000000..b3fc355
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * D2F - Convert double to float
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class D2F extends ConversionInstruction {
+
+    /** Convert double to float
+     */
+    public D2F() {
+        super(org.apache.tomcat.util.bcel.Constants.D2F);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitD2F(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/D2I.java b/java/org/apache/tomcat/util/bcel/generic/D2I.java
new file mode 100644 (file)
index 0000000..d78ed37
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * D2I - Convert double to int
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class D2I extends ConversionInstruction {
+
+    /** Convert double to int
+     */
+    public D2I() {
+        super(org.apache.tomcat.util.bcel.Constants.D2I);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitD2I(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/D2L.java b/java/org/apache/tomcat/util/bcel/generic/D2L.java
new file mode 100644 (file)
index 0000000..6b4c8c1
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * D2L - Convert double to long
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class D2L extends ConversionInstruction {
+
+    /** Convert double to long
+     */
+    public D2L() {
+        super(org.apache.tomcat.util.bcel.Constants.D2L);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitD2L(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DADD.java b/java/org/apache/tomcat/util/bcel/generic/DADD.java
new file mode 100644 (file)
index 0000000..0edba76
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DADD - Add doubles
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result1.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DADD extends ArithmeticInstruction {
+
+    /** Add doubles
+     */
+    public DADD() {
+        super(org.apache.tomcat.util.bcel.Constants.DADD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDADD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DALOAD.java b/java/org/apache/tomcat/util/bcel/generic/DALOAD.java
new file mode 100644 (file)
index 0000000..1c31541
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DALOAD - Load double from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load double from array
+     */
+    public DALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.DALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitDALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DASTORE.java b/java/org/apache/tomcat/util/bcel/generic/DASTORE.java
new file mode 100644 (file)
index 0000000..0bacc71
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DASTORE -  Store into double array
+ * <PRE>Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store double into array
+     */
+    public DASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.DASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitDASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DCMPG.java b/java/org/apache/tomcat/util/bcel/generic/DCMPG.java
new file mode 100644 (file)
index 0000000..0e9aca5
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DCMPG - Compare doubles: value1 > value2
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
+
+    public DCMPG() {
+        super(org.apache.tomcat.util.bcel.Constants.DCMPG, (short) 1);
+    }
+
+
+    /** @return Type.DOUBLE
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.DOUBLE;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitDCMPG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DCMPL.java b/java/org/apache/tomcat/util/bcel/generic/DCMPL.java
new file mode 100644 (file)
index 0000000..4ce1572
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DCMPL - Compare doubles: value1 < value2
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
+
+    public DCMPL() {
+        super(org.apache.tomcat.util.bcel.Constants.DCMPL, (short) 1);
+    }
+
+
+    /** @return Type.DOUBLE
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.DOUBLE;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitDCMPL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DCONST.java b/java/org/apache/tomcat/util/bcel/generic/DCONST.java
new file mode 100644 (file)
index 0000000..00fc1f9
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DCONST - Push 0.0 or 1.0, other values cause an exception
+ *
+ * <PRE>Stack: ... -&gt; ..., </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DCONST extends Instruction implements ConstantPushInstruction, TypedInstruction {
+
+    private double value;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    DCONST() {
+    }
+
+
+    public DCONST(double f) {
+        super(org.apache.tomcat.util.bcel.Constants.DCONST_0, (short) 1);
+        if (f == 0.0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.DCONST_0;
+        } else if (f == 1.0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.DCONST_1;
+        } else {
+            throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f);
+        }
+        value = f;
+    }
+
+
+    public Number getValue() {
+        return new Double(value);
+    }
+
+
+    /** @return Type.DOUBLE
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.DOUBLE;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitDCONST(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DDIV.java b/java/org/apache/tomcat/util/bcel/generic/DDIV.java
new file mode 100644 (file)
index 0000000..72df390
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DDIV -  Divide doubles
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DDIV extends ArithmeticInstruction {
+
+    /** Divide doubles
+     */
+    public DDIV() {
+        super(org.apache.tomcat.util.bcel.Constants.DDIV);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDDIV(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DLOAD.java b/java/org/apache/tomcat/util/bcel/generic/DLOAD.java
new file mode 100644 (file)
index 0000000..649f13c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DLOAD - Load double from local variable
+ * <PRE>Stack ... -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DLOAD extends LoadInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    DLOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.DLOAD, org.apache.tomcat.util.bcel.Constants.DLOAD_0);
+    }
+
+
+    /** Load double from local variable
+     * @param n index of local variable
+     */
+    public DLOAD(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.DLOAD, org.apache.tomcat.util.bcel.Constants.DLOAD_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitDLOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DMUL.java b/java/org/apache/tomcat/util/bcel/generic/DMUL.java
new file mode 100644 (file)
index 0000000..99d78b7
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DMUL - Multiply doubles
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DMUL extends ArithmeticInstruction {
+
+    /** Multiply doubles
+     */
+    public DMUL() {
+        super(org.apache.tomcat.util.bcel.Constants.DMUL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDMUL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DNEG.java b/java/org/apache/tomcat/util/bcel/generic/DNEG.java
new file mode 100644 (file)
index 0000000..51da499
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DNEG - Negate double
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DNEG extends ArithmeticInstruction {
+
+    public DNEG() {
+        super(org.apache.tomcat.util.bcel.Constants.DNEG);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDNEG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DREM.java b/java/org/apache/tomcat/util/bcel/generic/DREM.java
new file mode 100644 (file)
index 0000000..a6e03c0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DREM - Remainder of doubles
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DREM extends ArithmeticInstruction {
+
+    /** Remainder of doubles
+     */
+    public DREM() {
+        super(org.apache.tomcat.util.bcel.Constants.DREM);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDREM(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DRETURN.java b/java/org/apache/tomcat/util/bcel/generic/DRETURN.java
new file mode 100644 (file)
index 0000000..23b12ba
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DRETURN -  Return double from method
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DRETURN extends ReturnInstruction {
+
+    /** Return double from method
+     */
+    public DRETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.DRETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitDRETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DSTORE.java b/java/org/apache/tomcat/util/bcel/generic/DSTORE.java
new file mode 100644 (file)
index 0000000..f24f51c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DSTORE - Store double into local variable
+ * <pre>Stack: ..., value.word1, value.word2 -&gt; ... </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DSTORE extends StoreInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    DSTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.DSTORE, org.apache.tomcat.util.bcel.Constants.DSTORE_0);
+    }
+
+
+    /** Store double into local variable
+     * @param n index of local variable
+     */
+    public DSTORE(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.DSTORE, org.apache.tomcat.util.bcel.Constants.DSTORE_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitDSTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DSUB.java b/java/org/apache/tomcat/util/bcel/generic/DSUB.java
new file mode 100644 (file)
index 0000000..6ae95df
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DSUB - Substract doubles
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DSUB extends ArithmeticInstruction {
+
+    /** Substract doubles
+     */
+    public DSUB() {
+        super(org.apache.tomcat.util.bcel.Constants.DSUB);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitDSUB(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP.java b/java/org/apache/tomcat/util/bcel/generic/DUP.java
new file mode 100644 (file)
index 0000000..44bbfc8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP - Duplicate top operand stack word
+ * <PRE>Stack: ..., word -&gt; ..., word, word</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP extends StackInstruction implements PushInstruction {
+
+    public DUP() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitStackInstruction(this);
+        v.visitDUP(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP2.java b/java/org/apache/tomcat/util/bcel/generic/DUP2.java
new file mode 100644 (file)
index 0000000..55cc50b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP2 - Duplicate two top operand stack words
+ * <PRE>Stack: ..., word2, word1 -&gt; ..., word2, word1, word2, word1</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP2 extends StackInstruction implements PushInstruction {
+
+    public DUP2() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP2);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitStackInstruction(this);
+        v.visitDUP2(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP2_X1.java b/java/org/apache/tomcat/util/bcel/generic/DUP2_X1.java
new file mode 100644 (file)
index 0000000..70fb1b9
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP2_X1 - Duplicate two top operand stack words and put three down
+ * <PRE>Stack: ..., word3, word2, word1 -&gt; ..., word2, word1, word3, word2, word1</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP2_X1 extends StackInstruction {
+
+    public DUP2_X1() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP2_X1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackInstruction(this);
+        v.visitDUP2_X1(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP2_X2.java b/java/org/apache/tomcat/util/bcel/generic/DUP2_X2.java
new file mode 100644 (file)
index 0000000..1348268
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP2_X2 - Duplicate two top operand stack words and put four down
+ * <PRE>Stack: ..., word4, word3, word2, word1 -&gt; ..., word2, word1, word4, word3, word2, word1</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP2_X2 extends StackInstruction {
+
+    public DUP2_X2() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP2_X2);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackInstruction(this);
+        v.visitDUP2_X2(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP_X1.java b/java/org/apache/tomcat/util/bcel/generic/DUP_X1.java
new file mode 100644 (file)
index 0000000..f0dbcb3
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP_X1 - Duplicate top operand stack word and put two down
+ * <PRE>Stack: ..., word2, word1 -&gt; ..., word1, word2, word1</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP_X1 extends StackInstruction {
+
+    public DUP_X1() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP_X1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackInstruction(this);
+        v.visitDUP_X1(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/DUP_X2.java b/java/org/apache/tomcat/util/bcel/generic/DUP_X2.java
new file mode 100644 (file)
index 0000000..4ff230c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * DUP_X2 - Duplicate top operand stack word and put three down
+ * <PRE>Stack: ..., word3, word2, word1 -&gt; ..., word1, word3, word2, word1</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class DUP_X2 extends StackInstruction {
+
+    public DUP_X2() {
+        super(org.apache.tomcat.util.bcel.Constants.DUP_X2);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackInstruction(this);
+        v.visitDUP_X2(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/ElementValueGen.java
new file mode 100644 (file)
index 0000000..63e416c
--- /dev/null
@@ -0,0 +1,168 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.tomcat.util.bcel.classfile.AnnotationElementValue;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.ArrayElementValue;
+import org.apache.tomcat.util.bcel.classfile.ClassElementValue;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.EnumElementValue;
+import org.apache.tomcat.util.bcel.classfile.SimpleElementValue;
+
+public abstract class ElementValueGen
+{
+       protected int type;
+
+       protected ConstantPoolGen cpGen;
+
+       protected ElementValueGen(int type, ConstantPoolGen cpGen)
+       {
+               this.type = type;
+               this.cpGen = cpGen;
+       }
+
+       /**
+        * Subtypes return an immutable variant of the ElementValueGen
+        */
+       public abstract ElementValue getElementValue();
+
+       public int getElementValueType()
+       {
+               return type;
+       }
+
+       public abstract String stringifyValue();
+
+       public abstract void dump(DataOutputStream dos) throws IOException;
+
+       public static final int STRING = 's';
+
+       public static final int ENUM_CONSTANT = 'e';
+
+       public static final int CLASS = 'c';
+
+       public static final int ANNOTATION = '@';
+
+       public static final int ARRAY = '[';
+
+       public static final int PRIMITIVE_INT = 'I';
+
+       public static final int PRIMITIVE_BYTE = 'B';
+
+       public static final int PRIMITIVE_CHAR = 'C';
+
+       public static final int PRIMITIVE_DOUBLE = 'D';
+
+       public static final int PRIMITIVE_FLOAT = 'F';
+
+       public static final int PRIMITIVE_LONG = 'J';
+
+       public static final int PRIMITIVE_SHORT = 'S';
+
+       public static final int PRIMITIVE_BOOLEAN = 'Z';
+
+       public static ElementValueGen readElementValue(DataInputStream dis,
+                       ConstantPoolGen cpGen) throws IOException
+       {
+               int type = dis.readUnsignedByte();
+               switch (type)
+               {
+               case 'B': // byte
+                       return new SimpleElementValueGen(PRIMITIVE_BYTE, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'C': // char
+                       return new SimpleElementValueGen(PRIMITIVE_CHAR, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'D': // double
+                       return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'F': // float
+                       return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'I': // int
+                       return new SimpleElementValueGen(PRIMITIVE_INT, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'J': // long
+                       return new SimpleElementValueGen(PRIMITIVE_LONG, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'S': // short
+                       return new SimpleElementValueGen(PRIMITIVE_SHORT, dis
+                                       .readUnsignedShort(), cpGen);
+               case 'Z': // boolean
+                       return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis
+                                       .readUnsignedShort(), cpGen);
+               case 's': // String
+                       return new SimpleElementValueGen(STRING, dis.readUnsignedShort(),
+                                       cpGen);
+               case 'e': // Enum constant
+                       return new EnumElementValueGen(dis.readUnsignedShort(), dis
+                                       .readUnsignedShort(), cpGen);
+               case 'c': // Class
+                       return new ClassElementValueGen(dis.readUnsignedShort(), cpGen);
+               case '@': // Annotation
+                       // TODO: isRuntimeVisible ??????????
+                       // FIXME
+                       return new AnnotationElementValueGen(ANNOTATION,
+                                       new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen
+                                                       .getConstantPool(), true), cpGen, false), cpGen);
+               case '[': // Array
+                       int numArrayVals = dis.readUnsignedShort();
+                       ElementValue[] evalues = new ElementValue[numArrayVals];
+                       for (int j = 0; j < numArrayVals; j++)
+                       {
+                               evalues[j] = ElementValue.readElementValue(dis, cpGen
+                                               .getConstantPool());
+                       }
+                       return new ArrayElementValueGen(ARRAY, evalues, cpGen);
+               default:
+                       throw new RuntimeException(
+                                       "Unexpected element value kind in annotation: " + type);
+               }
+       }
+
+       protected ConstantPoolGen getConstantPool()
+       {
+               return cpGen;
+       }
+
+       /**
+        * Creates an (modifiable) ElementValueGen copy of an (immutable)
+        * ElementValue - constant pool is assumed correct.
+        */
+       public static ElementValueGen copy(ElementValue value,
+                       ConstantPoolGen cpool, boolean copyPoolEntries)
+       {
+               switch (value.getElementValueType())
+               {
+               case 'B': // byte
+               case 'C': // char
+               case 'D': // double
+               case 'F': // float
+               case 'I': // int
+               case 'J': // long
+               case 'S': // short
+               case 'Z': // boolean
+               case 's': // String
+                       return new SimpleElementValueGen((SimpleElementValue) value, cpool,
+                                       copyPoolEntries);
+               case 'e': // Enum constant
+                       return new EnumElementValueGen((EnumElementValue) value, cpool,
+                                       copyPoolEntries);
+               case '@': // Annotation
+                       return new AnnotationElementValueGen(
+                                       (AnnotationElementValue) value, cpool, copyPoolEntries);
+               case '[': // Array
+                       return new ArrayElementValueGen((ArrayElementValue) value, cpool,
+                                       copyPoolEntries);
+               case 'c': // Class
+                       return new ClassElementValueGen((ClassElementValue) value, cpool,
+                                       copyPoolEntries);
+               default:
+                       throw new RuntimeException("Not implemented yet! ("
+                                       + value.getElementValueType() + ")");
+               }
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ElementValuePairGen.java b/java/org/apache/tomcat/util/bcel/generic/ElementValuePairGen.java
new file mode 100755 (executable)
index 0000000..590c10c
--- /dev/null
@@ -0,0 +1,93 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.ElementValuePair;
+
+public class ElementValuePairGen
+{
+       private int nameIdx;
+
+       private ElementValueGen value;
+
+       private ConstantPoolGen cpool;
+
+       public ElementValuePairGen(ElementValuePair nvp, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               this.cpool = cpool;
+               // J5ASSERT:
+               // Could assert nvp.getNameString() points to the same thing as
+               // cpool.getConstant(nvp.getNameIndex())
+               // if
+               // (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes()))
+               // {
+               // throw new RuntimeException("envp buggered");
+               // }
+               if (copyPoolEntries)
+               {
+                       nameIdx = cpool.addUtf8(nvp.getNameString());
+               }
+               else
+               {
+                       nameIdx = nvp.getNameIndex();
+               }
+               value = ElementValueGen.copy(nvp.getValue(), cpool, copyPoolEntries);
+       }
+
+       /**
+        * Retrieve an immutable version of this ElementNameValuePairGen
+        */
+       public ElementValuePair getElementNameValuePair()
+       {
+               ElementValue immutableValue = value.getElementValue();
+               return new ElementValuePair(nameIdx, immutableValue, cpool
+                               .getConstantPool());
+       }
+
+       protected ElementValuePairGen(int idx, ElementValueGen value,
+                       ConstantPoolGen cpool)
+       {
+               this.nameIdx = idx;
+               this.value = value;
+               this.cpool = cpool;
+       }
+
+       public ElementValuePairGen(String name, ElementValueGen value,
+                       ConstantPoolGen cpool)
+       {
+               this.nameIdx = cpool.addUtf8(name);
+               this.value = value;
+               this.cpool = cpool;
+       }
+
+       protected void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeShort(nameIdx); // u2 name of the element
+               value.dump(dos);
+       }
+
+       public int getNameIndex()
+       {
+               return nameIdx;
+       }
+
+       public final String getNameString()
+       {
+               // ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx);
+               return ((ConstantUtf8) cpool.getConstant(nameIdx)).getBytes();
+       }
+
+       public final ElementValueGen getValue()
+       {
+               return value;
+       }
+
+       public String toString()
+       {
+               return "ElementValuePair:[" + getNameString() + "="
+                               + value.stringifyValue() + "]";
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/EmptyVisitor.java b/java/org/apache/tomcat/util/bcel/generic/EmptyVisitor.java
new file mode 100644 (file)
index 0000000..52507d5
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Supplies empty method bodies to be overridden by subclasses.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class EmptyVisitor implements Visitor {
+
+    public void visitStackInstruction( StackInstruction obj ) {
+    }
+
+
+    public void visitLocalVariableInstruction( LocalVariableInstruction obj ) {
+    }
+
+
+    public void visitBranchInstruction( BranchInstruction obj ) {
+    }
+
+
+    public void visitLoadClass( LoadClass obj ) {
+    }
+
+
+    public void visitFieldInstruction( FieldInstruction obj ) {
+    }
+
+
+    public void visitIfInstruction( IfInstruction obj ) {
+    }
+
+
+    public void visitConversionInstruction( ConversionInstruction obj ) {
+    }
+
+
+    public void visitPopInstruction( PopInstruction obj ) {
+    }
+
+
+    public void visitJsrInstruction( JsrInstruction obj ) {
+    }
+
+
+    public void visitGotoInstruction( GotoInstruction obj ) {
+    }
+
+
+    public void visitStoreInstruction( StoreInstruction obj ) {
+    }
+
+
+    public void visitTypedInstruction( TypedInstruction obj ) {
+    }
+
+
+    public void visitSelect( Select obj ) {
+    }
+
+
+    public void visitUnconditionalBranch( UnconditionalBranch obj ) {
+    }
+
+
+    public void visitPushInstruction( PushInstruction obj ) {
+    }
+
+
+    public void visitArithmeticInstruction( ArithmeticInstruction obj ) {
+    }
+
+
+    public void visitCPInstruction( CPInstruction obj ) {
+    }
+
+
+    public void visitInvokeInstruction( InvokeInstruction obj ) {
+    }
+
+
+    public void visitArrayInstruction( ArrayInstruction obj ) {
+    }
+
+
+    public void visitAllocationInstruction( AllocationInstruction obj ) {
+    }
+
+
+    public void visitReturnInstruction( ReturnInstruction obj ) {
+    }
+
+
+    public void visitFieldOrMethod( FieldOrMethod obj ) {
+    }
+
+
+    public void visitConstantPushInstruction( ConstantPushInstruction obj ) {
+    }
+
+
+    public void visitExceptionThrower( ExceptionThrower obj ) {
+    }
+
+
+    public void visitLoadInstruction( LoadInstruction obj ) {
+    }
+
+
+    public void visitVariableLengthInstruction( VariableLengthInstruction obj ) {
+    }
+
+
+    public void visitStackProducer( StackProducer obj ) {
+    }
+
+
+    public void visitStackConsumer( StackConsumer obj ) {
+    }
+
+
+    public void visitACONST_NULL( ACONST_NULL obj ) {
+    }
+
+
+    public void visitGETSTATIC( GETSTATIC obj ) {
+    }
+
+
+    public void visitIF_ICMPLT( IF_ICMPLT obj ) {
+    }
+
+
+    public void visitMONITOREXIT( MONITOREXIT obj ) {
+    }
+
+
+    public void visitIFLT( IFLT obj ) {
+    }
+
+
+    public void visitLSTORE( LSTORE obj ) {
+    }
+
+
+    public void visitPOP2( POP2 obj ) {
+    }
+
+
+    public void visitBASTORE( BASTORE obj ) {
+    }
+
+
+    public void visitISTORE( ISTORE obj ) {
+    }
+
+
+    public void visitCHECKCAST( CHECKCAST obj ) {
+    }
+
+
+    public void visitFCMPG( FCMPG obj ) {
+    }
+
+
+    public void visitI2F( I2F obj ) {
+    }
+
+
+    public void visitATHROW( ATHROW obj ) {
+    }
+
+
+    public void visitDCMPL( DCMPL obj ) {
+    }
+
+
+    public void visitARRAYLENGTH( ARRAYLENGTH obj ) {
+    }
+
+
+    public void visitDUP( DUP obj ) {
+    }
+
+
+    public void visitINVOKESTATIC( INVOKESTATIC obj ) {
+    }
+
+
+    public void visitLCONST( LCONST obj ) {
+    }
+
+
+    public void visitDREM( DREM obj ) {
+    }
+
+
+    public void visitIFGE( IFGE obj ) {
+    }
+
+
+    public void visitCALOAD( CALOAD obj ) {
+    }
+
+
+    public void visitLASTORE( LASTORE obj ) {
+    }
+
+
+    public void visitI2D( I2D obj ) {
+    }
+
+
+    public void visitDADD( DADD obj ) {
+    }
+
+
+    public void visitINVOKESPECIAL( INVOKESPECIAL obj ) {
+    }
+
+
+    public void visitIAND( IAND obj ) {
+    }
+
+
+    public void visitPUTFIELD( PUTFIELD obj ) {
+    }
+
+
+    public void visitILOAD( ILOAD obj ) {
+    }
+
+
+    public void visitDLOAD( DLOAD obj ) {
+    }
+
+
+    public void visitDCONST( DCONST obj ) {
+    }
+
+
+    public void visitNEW( NEW obj ) {
+    }
+
+
+    public void visitIFNULL( IFNULL obj ) {
+    }
+
+
+    public void visitLSUB( LSUB obj ) {
+    }
+
+
+    public void visitL2I( L2I obj ) {
+    }
+
+
+    public void visitISHR( ISHR obj ) {
+    }
+
+
+    public void visitTABLESWITCH( TABLESWITCH obj ) {
+    }
+
+
+    public void visitIINC( IINC obj ) {
+    }
+
+
+    public void visitDRETURN( DRETURN obj ) {
+    }
+
+
+    public void visitFSTORE( FSTORE obj ) {
+    }
+
+
+    public void visitDASTORE( DASTORE obj ) {
+    }
+
+
+    public void visitIALOAD( IALOAD obj ) {
+    }
+
+
+    public void visitDDIV( DDIV obj ) {
+    }
+
+
+    public void visitIF_ICMPGE( IF_ICMPGE obj ) {
+    }
+
+
+    public void visitLAND( LAND obj ) {
+    }
+
+
+    public void visitIDIV( IDIV obj ) {
+    }
+
+
+    public void visitLOR( LOR obj ) {
+    }
+
+
+    public void visitCASTORE( CASTORE obj ) {
+    }
+
+
+    public void visitFREM( FREM obj ) {
+    }
+
+
+    public void visitLDC( LDC obj ) {
+    }
+
+
+    public void visitBIPUSH( BIPUSH obj ) {
+    }
+
+
+    public void visitDSTORE( DSTORE obj ) {
+    }
+
+
+    public void visitF2L( F2L obj ) {
+    }
+
+
+    public void visitFMUL( FMUL obj ) {
+    }
+
+
+    public void visitLLOAD( LLOAD obj ) {
+    }
+
+
+    public void visitJSR( JSR obj ) {
+    }
+
+
+    public void visitFSUB( FSUB obj ) {
+    }
+
+
+    public void visitSASTORE( SASTORE obj ) {
+    }
+
+
+    public void visitALOAD( ALOAD obj ) {
+    }
+
+
+    public void visitDUP2_X2( DUP2_X2 obj ) {
+    }
+
+
+    public void visitRETURN( RETURN obj ) {
+    }
+
+
+    public void visitDALOAD( DALOAD obj ) {
+    }
+
+
+    public void visitSIPUSH( SIPUSH obj ) {
+    }
+
+
+    public void visitDSUB( DSUB obj ) {
+    }
+
+
+    public void visitL2F( L2F obj ) {
+    }
+
+
+    public void visitIF_ICMPGT( IF_ICMPGT obj ) {
+    }
+
+
+    public void visitF2D( F2D obj ) {
+    }
+
+
+    public void visitI2L( I2L obj ) {
+    }
+
+
+    public void visitIF_ACMPNE( IF_ACMPNE obj ) {
+    }
+
+
+    public void visitPOP( POP obj ) {
+    }
+
+
+    public void visitI2S( I2S obj ) {
+    }
+
+
+    public void visitIFEQ( IFEQ obj ) {
+    }
+
+
+    public void visitSWAP( SWAP obj ) {
+    }
+
+
+    public void visitIOR( IOR obj ) {
+    }
+
+
+    public void visitIREM( IREM obj ) {
+    }
+
+
+    public void visitIASTORE( IASTORE obj ) {
+    }
+
+
+    public void visitNEWARRAY( NEWARRAY obj ) {
+    }
+
+
+    public void visitINVOKEINTERFACE( INVOKEINTERFACE obj ) {
+    }
+
+
+    public void visitINEG( INEG obj ) {
+    }
+
+
+    public void visitLCMP( LCMP obj ) {
+    }
+
+
+    public void visitJSR_W( JSR_W obj ) {
+    }
+
+
+    public void visitMULTIANEWARRAY( MULTIANEWARRAY obj ) {
+    }
+
+
+    public void visitDUP_X2( DUP_X2 obj ) {
+    }
+
+
+    public void visitSALOAD( SALOAD obj ) {
+    }
+
+
+    public void visitIFNONNULL( IFNONNULL obj ) {
+    }
+
+
+    public void visitDMUL( DMUL obj ) {
+    }
+
+
+    public void visitIFNE( IFNE obj ) {
+    }
+
+
+    public void visitIF_ICMPLE( IF_ICMPLE obj ) {
+    }
+
+
+    public void visitLDC2_W( LDC2_W obj ) {
+    }
+
+
+    public void visitGETFIELD( GETFIELD obj ) {
+    }
+
+
+    public void visitLADD( LADD obj ) {
+    }
+
+
+    public void visitNOP( NOP obj ) {
+    }
+
+
+    public void visitFALOAD( FALOAD obj ) {
+    }
+
+
+    public void visitINSTANCEOF( INSTANCEOF obj ) {
+    }
+
+
+    public void visitIFLE( IFLE obj ) {
+    }
+
+
+    public void visitLXOR( LXOR obj ) {
+    }
+
+
+    public void visitLRETURN( LRETURN obj ) {
+    }
+
+
+    public void visitFCONST( FCONST obj ) {
+    }
+
+
+    public void visitIUSHR( IUSHR obj ) {
+    }
+
+
+    public void visitBALOAD( BALOAD obj ) {
+    }
+
+
+    public void visitDUP2( DUP2 obj ) {
+    }
+
+
+    public void visitIF_ACMPEQ( IF_ACMPEQ obj ) {
+    }
+
+
+    public void visitIMPDEP1( IMPDEP1 obj ) {
+    }
+
+
+    public void visitMONITORENTER( MONITORENTER obj ) {
+    }
+
+
+    public void visitLSHL( LSHL obj ) {
+    }
+
+
+    public void visitDCMPG( DCMPG obj ) {
+    }
+
+
+    public void visitD2L( D2L obj ) {
+    }
+
+
+    public void visitIMPDEP2( IMPDEP2 obj ) {
+    }
+
+
+    public void visitL2D( L2D obj ) {
+    }
+
+
+    public void visitRET( RET obj ) {
+    }
+
+
+    public void visitIFGT( IFGT obj ) {
+    }
+
+
+    public void visitIXOR( IXOR obj ) {
+    }
+
+
+    public void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ) {
+    }
+
+
+    public void visitFASTORE( FASTORE obj ) {
+    }
+
+
+    public void visitIRETURN( IRETURN obj ) {
+    }
+
+
+    public void visitIF_ICMPNE( IF_ICMPNE obj ) {
+    }
+
+
+    public void visitFLOAD( FLOAD obj ) {
+    }
+
+
+    public void visitLDIV( LDIV obj ) {
+    }
+
+
+    public void visitPUTSTATIC( PUTSTATIC obj ) {
+    }
+
+
+    public void visitAALOAD( AALOAD obj ) {
+    }
+
+
+    public void visitD2I( D2I obj ) {
+    }
+
+
+    public void visitIF_ICMPEQ( IF_ICMPEQ obj ) {
+    }
+
+
+    public void visitAASTORE( AASTORE obj ) {
+    }
+
+
+    public void visitARETURN( ARETURN obj ) {
+    }
+
+
+    public void visitDUP2_X1( DUP2_X1 obj ) {
+    }
+
+
+    public void visitFNEG( FNEG obj ) {
+    }
+
+
+    public void visitGOTO_W( GOTO_W obj ) {
+    }
+
+
+    public void visitD2F( D2F obj ) {
+    }
+
+
+    public void visitGOTO( GOTO obj ) {
+    }
+
+
+    public void visitISUB( ISUB obj ) {
+    }
+
+
+    public void visitF2I( F2I obj ) {
+    }
+
+
+    public void visitDNEG( DNEG obj ) {
+    }
+
+
+    public void visitICONST( ICONST obj ) {
+    }
+
+
+    public void visitFDIV( FDIV obj ) {
+    }
+
+
+    public void visitI2B( I2B obj ) {
+    }
+
+
+    public void visitLNEG( LNEG obj ) {
+    }
+
+
+    public void visitLREM( LREM obj ) {
+    }
+
+
+    public void visitIMUL( IMUL obj ) {
+    }
+
+
+    public void visitIADD( IADD obj ) {
+    }
+
+
+    public void visitLSHR( LSHR obj ) {
+    }
+
+
+    public void visitLOOKUPSWITCH( LOOKUPSWITCH obj ) {
+    }
+
+
+    public void visitDUP_X1( DUP_X1 obj ) {
+    }
+
+
+    public void visitFCMPL( FCMPL obj ) {
+    }
+
+
+    public void visitI2C( I2C obj ) {
+    }
+
+
+    public void visitLMUL( LMUL obj ) {
+    }
+
+
+    public void visitLUSHR( LUSHR obj ) {
+    }
+
+
+    public void visitISHL( ISHL obj ) {
+    }
+
+
+    public void visitLALOAD( LALOAD obj ) {
+    }
+
+
+    public void visitASTORE( ASTORE obj ) {
+    }
+
+
+    public void visitANEWARRAY( ANEWARRAY obj ) {
+    }
+
+
+    public void visitFRETURN( FRETURN obj ) {
+    }
+
+
+    public void visitFADD( FADD obj ) {
+    }
+
+
+    public void visitBREAKPOINT( BREAKPOINT obj ) {
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/EnumElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/EnumElementValueGen.java
new file mode 100644 (file)
index 0000000..2e78d1e
--- /dev/null
@@ -0,0 +1,119 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.EnumElementValue;
+
+public class EnumElementValueGen extends ElementValueGen
+{
+       // For enum types, these two indices point to the type and value
+       private int typeIdx;
+
+       private int valueIdx;
+
+       /**
+        * This ctor assumes the constant pool already contains the right type and
+        * value - as indicated by typeIdx and valueIdx. This ctor is used for
+        * deserialization
+        */
+       protected EnumElementValueGen(int typeIdx, int valueIdx,
+                       ConstantPoolGen cpool)
+       {
+               super(ElementValueGen.ENUM_CONSTANT, cpool);
+               if (type != ENUM_CONSTANT)
+                       throw new RuntimeException(
+                                       "Only element values of type enum can be built with this ctor - type specified: " + type);
+               this.typeIdx = typeIdx;
+               this.valueIdx = valueIdx;
+       }
+
+       /**
+        * Return immutable variant of this EnumElementValue
+        */
+       public ElementValue getElementValue()
+       {
+               System.err.println("Duplicating value: " + getEnumTypeString() + ":"
+                               + getEnumValueString());
+               return new EnumElementValue(type, typeIdx, valueIdx, cpGen
+                               .getConstantPool());
+       }
+
+       public EnumElementValueGen(ObjectType t, String value, ConstantPoolGen cpool)
+       {
+               super(ElementValueGen.ENUM_CONSTANT, cpool);
+               typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t);
+               valueIdx = cpool.addUtf8(value);// was addString(value);
+       }
+
+       public EnumElementValueGen(EnumElementValue value, ConstantPoolGen cpool,
+                       boolean copyPoolEntries)
+       {
+               super(ENUM_CONSTANT, cpool);
+               if (copyPoolEntries)
+               {
+                       typeIdx = cpool.addUtf8(value.getEnumTypeString());// was
+                                                                                                                               // addClass(value.getEnumTypeString());
+                       valueIdx = cpool.addUtf8(value.getEnumValueString()); // was
+                                                                                                                                       // addString(value.getEnumValueString());
+               }
+               else
+               {
+                       typeIdx = value.getTypeIndex();
+                       valueIdx = value.getValueIndex();
+               }
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 type of value (ENUM_CONSTANT == 'e')
+               dos.writeShort(typeIdx); // u2
+               dos.writeShort(valueIdx); // u2
+       }
+
+       public String stringifyValue()
+       {
+               ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(
+                               valueIdx);
+               return cu8.getBytes();
+               // ConstantString cu8 =
+               // (ConstantString)getConstantPool().getConstant(valueIdx);
+               // return
+               // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
+       }
+
+       // BCELBUG: Should we need to call utility.signatureToString() on the output
+       // here?
+       public String getEnumTypeString()
+       {
+               // Constant cc = getConstantPool().getConstant(typeIdx);
+               // ConstantClass cu8 =
+               // (ConstantClass)getConstantPool().getConstant(typeIdx);
+               // return
+               // ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes();
+               return ((ConstantUtf8) getConstantPool().getConstant(typeIdx))
+                               .getBytes();
+               // return Utility.signatureToString(cu8.getBytes());
+       }
+
+       public String getEnumValueString()
+       {
+               return ((ConstantUtf8) getConstantPool().getConstant(valueIdx))
+                               .getBytes();
+               // ConstantString cu8 =
+               // (ConstantString)getConstantPool().getConstant(valueIdx);
+               // return
+               // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
+       }
+
+       public int getValueIndex()
+       {
+               return valueIdx;
+       }
+
+       public int getTypeIndex()
+       {
+               return typeIdx;
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ExceptionThrower.java b/java/org/apache/tomcat/util/bcel/generic/ExceptionThrower.java
new file mode 100644 (file)
index 0000000..f62cca0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote an instruction that may throw a run-time or a linking
+ * exception (or both) during execution.  This is not quite the truth
+ * as such; because all instructions may throw an
+ * java.lang.VirtualMachineError. These exceptions are omitted.
+ * 
+ * The Lava Language Specification specifies exactly which
+ * <i>RUN-TIME</i> and which <i>LINKING</i> exceptions each
+ * instruction may throw which is reflected by the implementers.  Due
+ * to the structure of the JVM specification, it may be possible that
+ * an Instruction implementing this interface returns a Class[] of
+ * size 0.
+ *
+ * Please note that we speak of an "exception" here when we mean any
+ * "Throwable" object; so this term is equally used for "Exception"
+ * and "Error" objects.
+ *
+ * @version $Id$
+ * @author  Enver Haase
+ */
+public interface ExceptionThrower {
+
+    public java.lang.Class[] getExceptions();
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/F2D.java b/java/org/apache/tomcat/util/bcel/generic/F2D.java
new file mode 100644 (file)
index 0000000..d65deed
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * F2D - Convert float to double
+ * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class F2D extends ConversionInstruction {
+
+    /** Convert float to double
+     */
+    public F2D() {
+        super(org.apache.tomcat.util.bcel.Constants.F2D);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitF2D(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/F2I.java b/java/org/apache/tomcat/util/bcel/generic/F2I.java
new file mode 100644 (file)
index 0000000..4d19be9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * F2I - Convert float to int
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class F2I extends ConversionInstruction {
+
+    /** Convert float to int
+     */
+    public F2I() {
+        super(org.apache.tomcat.util.bcel.Constants.F2I);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitF2I(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/F2L.java b/java/org/apache/tomcat/util/bcel/generic/F2L.java
new file mode 100644 (file)
index 0000000..d102be2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * F2L - Convert float to long
+ * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class F2L extends ConversionInstruction {
+
+    /** Convert float to long
+     */
+    public F2L() {
+        super(org.apache.tomcat.util.bcel.Constants.F2L);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitF2L(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FADD.java b/java/org/apache/tomcat/util/bcel/generic/FADD.java
new file mode 100644 (file)
index 0000000..464c8d8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FADD - Add floats
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FADD extends ArithmeticInstruction {
+
+    /** Add floats
+     */
+    public FADD() {
+        super(org.apache.tomcat.util.bcel.Constants.FADD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFADD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FALOAD.java b/java/org/apache/tomcat/util/bcel/generic/FALOAD.java
new file mode 100644 (file)
index 0000000..3f9daa5
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FALOAD - Load float from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load float from array
+     */
+    public FALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.FALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitFALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FASTORE.java b/java/org/apache/tomcat/util/bcel/generic/FASTORE.java
new file mode 100644 (file)
index 0000000..d4691fa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FASTORE -  Store into float array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store float into array
+     */
+    public FASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.FASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitFASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FCMPG.java b/java/org/apache/tomcat/util/bcel/generic/FCMPG.java
new file mode 100644 (file)
index 0000000..3e1f3ca
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FCMPG - Compare floats: value1 > value2
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
+
+    public FCMPG() {
+        super(org.apache.tomcat.util.bcel.Constants.FCMPG, (short) 1);
+    }
+
+
+    /** @return Type.FLOAT
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.FLOAT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitFCMPG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FCMPL.java b/java/org/apache/tomcat/util/bcel/generic/FCMPL.java
new file mode 100644 (file)
index 0000000..3006180
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FCMPL - Compare floats: value1 < value2
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
+
+    public FCMPL() {
+        super(org.apache.tomcat.util.bcel.Constants.FCMPL, (short) 1);
+    }
+
+
+    /** @return Type.FLOAT
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.FLOAT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitFCMPL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FCONST.java b/java/org/apache/tomcat/util/bcel/generic/FCONST.java
new file mode 100644 (file)
index 0000000..ffa6123
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FCONST - Push 0.0, 1.0 or 2.0, other values cause an exception
+ *
+ * <PRE>Stack: ... -&gt; ..., </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FCONST extends Instruction implements ConstantPushInstruction, TypedInstruction {
+
+    private float value;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    FCONST() {
+    }
+
+
+    public FCONST(float f) {
+        super(org.apache.tomcat.util.bcel.Constants.FCONST_0, (short) 1);
+        if (f == 0.0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.FCONST_0;
+        } else if (f == 1.0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.FCONST_1;
+        } else if (f == 2.0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.FCONST_2;
+        } else {
+            throw new ClassGenException("FCONST can be used only for 0.0, 1.0 and 2.0: " + f);
+        }
+        value = f;
+    }
+
+
+    public Number getValue() {
+        return new Float(value);
+    }
+
+
+    /** @return Type.FLOAT
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.FLOAT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitFCONST(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FDIV.java b/java/org/apache/tomcat/util/bcel/generic/FDIV.java
new file mode 100644 (file)
index 0000000..aaec456
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * FDIV - Divide floats
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FDIV extends ArithmeticInstruction {
+
+    /** Divide floats
+     */
+    public FDIV() {
+        super(org.apache.tomcat.util.bcel.Constants.FDIV);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFDIV(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FLOAD.java b/java/org/apache/tomcat/util/bcel/generic/FLOAD.java
new file mode 100644 (file)
index 0000000..007bae1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FLOAD - Load float from local variable
+ * <PRE>Stack ... -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FLOAD extends LoadInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    FLOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.FLOAD, org.apache.tomcat.util.bcel.Constants.FLOAD_0);
+    }
+
+
+    /** Load float from local variable
+     * @param n index of local variable
+     */
+    public FLOAD(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.FLOAD, org.apache.tomcat.util.bcel.Constants.FLOAD_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitFLOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FMUL.java b/java/org/apache/tomcat/util/bcel/generic/FMUL.java
new file mode 100644 (file)
index 0000000..e0c786f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * FMUL - Multiply floats
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FMUL extends ArithmeticInstruction {
+
+    /** Multiply floats
+     */
+    public FMUL() {
+        super(org.apache.tomcat.util.bcel.Constants.FMUL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFMUL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FNEG.java b/java/org/apache/tomcat/util/bcel/generic/FNEG.java
new file mode 100644 (file)
index 0000000..56aeb31
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FNEG - Negate float
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FNEG extends ArithmeticInstruction {
+
+    public FNEG() {
+        super(org.apache.tomcat.util.bcel.Constants.FNEG);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFNEG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FREM.java b/java/org/apache/tomcat/util/bcel/generic/FREM.java
new file mode 100644 (file)
index 0000000..2f3e836
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * FREM - Remainder of floats
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FREM extends ArithmeticInstruction {
+
+    /** Remainder of floats
+     */
+    public FREM() {
+        super(org.apache.tomcat.util.bcel.Constants.FREM);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFREM(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FRETURN.java b/java/org/apache/tomcat/util/bcel/generic/FRETURN.java
new file mode 100644 (file)
index 0000000..db49cbf
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FRETURN -  Return float from method
+ * <PRE>Stack: ..., value -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FRETURN extends ReturnInstruction {
+
+    /** Return float from method
+     */
+    public FRETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.FRETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitFRETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FSTORE.java b/java/org/apache/tomcat/util/bcel/generic/FSTORE.java
new file mode 100644 (file)
index 0000000..f3b52c0
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * FSTORE - Store float into local variable
+ * <PRE>Stack: ..., value -&gt; ... </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FSTORE extends StoreInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    FSTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.FSTORE, org.apache.tomcat.util.bcel.Constants.FSTORE_0);
+    }
+
+
+    /** Store float into local variable
+     * @param n index of local variable
+     */
+    public FSTORE(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.FSTORE, org.apache.tomcat.util.bcel.Constants.FSTORE_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitFSTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FSUB.java b/java/org/apache/tomcat/util/bcel/generic/FSUB.java
new file mode 100644 (file)
index 0000000..c496bfa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * FSUB - Substract floats
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class FSUB extends ArithmeticInstruction {
+
+    /** Substract floats
+     */
+    public FSUB() {
+        super(org.apache.tomcat.util.bcel.Constants.FSUB);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitFSUB(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FieldGen.java b/java/org/apache/tomcat/util/bcel/generic/FieldGen.java
new file mode 100644 (file)
index 0000000..325399b
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.Annotations;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.classfile.ConstantObject;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantValue;
+import org.apache.tomcat.util.bcel.classfile.Field;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/** 
+ * Template class for building up a field.  The only extraordinary thing
+ * one can do is to add a constant value attribute to a field (which must of
+ * course be compatible with to the declared type).
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Field
+ */
+public class FieldGen extends FieldGenOrMethodGen {
+
+    private Object value = null;
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            FieldGen THIS = (FieldGen) o1;
+            FieldGen THAT = (FieldGen) o2;
+            return THIS.getName().equals(THAT.getName())
+                    && THIS.getSignature().equals(THAT.getSignature());
+        }
+
+
+        public int hashCode( Object o ) {
+            FieldGen THIS = (FieldGen) o;
+            return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+        }
+    };
+
+
+    /**
+     * Declare a field. If it is static (isStatic() == true) and has a
+     * basic type like int or String it may have an initial value
+     * associated with it as defined by setInitValue().
+     *
+     * @param access_flags access qualifiers
+     * @param type  field type
+     * @param name field name
+     * @param cp constant pool
+     */
+    public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) {
+        setAccessFlags(access_flags);
+        setType(type);
+        setName(name);
+        setConstantPool(cp);
+    }
+
+
+    /**
+     * Instantiate from existing field.
+     *
+     * @param field Field object
+     * @param cp constant pool (must contain the same entries as the field's constant pool)
+     */
+    public FieldGen(Field field, ConstantPoolGen cp) {
+        this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp);
+        Attribute[] attrs = field.getAttributes();
+        for (int i = 0; i < attrs.length; i++) {
+            if (attrs[i] instanceof ConstantValue) {
+                setValue(((ConstantValue) attrs[i]).getConstantValueIndex());
+            } else if (attrs[i] instanceof Annotations) {
+               Annotations runtimeAnnotations = (Annotations)attrs[i];
+                       AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries();
+                       for (int j = 0; j < annotationEntries.length; j++) {
+                               AnnotationEntry element = annotationEntries[j];
+                               addAnnotationEntry(new AnnotationEntryGen(element,cp,false));
+                       }
+            } else {
+                addAttribute(attrs[i]);
+            }
+        }
+    }
+
+
+    private void setValue( int index ) {
+        ConstantPool cp = this.cp.getConstantPool();
+        Constant c = cp.getConstant(index);
+        value = ((ConstantObject) c).getConstantValue(cp);
+    }
+
+
+    /**
+     * Set (optional) initial value of field, otherwise it will be set to null/0/false
+     * by the JVM automatically.
+     */
+    public void setInitValue( String str ) {
+        checkType(new ObjectType("java.lang.String"));
+        if (str != null) {
+            value = str;
+        }
+    }
+
+
+    public void setInitValue( long l ) {
+        checkType(Type.LONG);
+        if (l != 0L) {
+            value = new Long(l);
+        }
+    }
+
+
+    public void setInitValue( int i ) {
+        checkType(Type.INT);
+        if (i != 0) {
+            value = new Integer(i);
+        }
+    }
+
+
+    public void setInitValue( short s ) {
+        checkType(Type.SHORT);
+        if (s != 0) {
+            value = new Integer(s);
+        }
+    }
+
+
+    public void setInitValue( char c ) {
+        checkType(Type.CHAR);
+        if (c != 0) {
+            value = new Integer(c);
+        }
+    }
+
+
+    public void setInitValue( byte b ) {
+        checkType(Type.BYTE);
+        if (b != 0) {
+            value = new Integer(b);
+        }
+    }
+
+
+    public void setInitValue( boolean b ) {
+        checkType(Type.BOOLEAN);
+        if (b) {
+            value = new Integer(1);
+        }
+    }
+
+
+    public void setInitValue( float f ) {
+        checkType(Type.FLOAT);
+        if (f != 0.0) {
+            value = new Float(f);
+        }
+    }
+
+
+    public void setInitValue( double d ) {
+        checkType(Type.DOUBLE);
+        if (d != 0.0) {
+            value = new Double(d);
+        }
+    }
+
+
+    /** Remove any initial value.
+     */
+    public void cancelInitValue() {
+        value = null;
+    }
+
+
+    private void checkType( Type atype ) {
+        if (type == null) {
+            throw new ClassGenException("You haven't defined the type of the field yet");
+        }
+        if (!isFinal()) {
+            throw new ClassGenException("Only final fields may have an initial value!");
+        }
+        if (!type.equals(atype)) {
+            throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype);
+        }
+    }
+
+
+    /**
+     * Get field object after having set up all necessary values.
+     */
+    public Field getField() {
+        String signature = getSignature();
+        int name_index = cp.addUtf8(name);
+        int signature_index = cp.addUtf8(signature);
+        if (value != null) {
+            checkType(type);
+            int index = addConstant();
+            addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp
+                    .getConstantPool()));
+        }
+        addAnnotationsAsAttribute(cp);
+        return new Field(access_flags, name_index, signature_index, getAttributes(), cp
+                .getConstantPool());
+    }
+    
+    private void addAnnotationsAsAttribute(ConstantPoolGen cp) {
+       Attribute[] attrs = Utility.getAnnotationAttributes(cp,annotation_vec);
+        for (int i = 0; i < attrs.length; i++) {
+               addAttribute(attrs[i]);
+       }
+      }
+
+
+    private int addConstant() {
+        switch (type.getType()) {
+            case Constants.T_INT:
+            case Constants.T_CHAR:
+            case Constants.T_BYTE:
+            case Constants.T_BOOLEAN:
+            case Constants.T_SHORT:
+                return cp.addInteger(((Integer) value).intValue());
+            case Constants.T_FLOAT:
+                return cp.addFloat(((Float) value).floatValue());
+            case Constants.T_DOUBLE:
+                return cp.addDouble(((Double) value).doubleValue());
+            case Constants.T_LONG:
+                return cp.addLong(((Long) value).longValue());
+            case Constants.T_REFERENCE:
+                return cp.addString(((String) value));
+            default:
+                throw new RuntimeException("Oops: Unhandled : " + type.getType());
+        }
+    }
+
+
+    public String getSignature() {
+        return type.getSignature();
+    }
+
+    private List observers;
+
+
+    /** Add observer for this object.
+     */
+    public void addObserver( FieldObserver o ) {
+        if (observers == null) {
+            observers = new ArrayList();
+        }
+        observers.add(o);
+    }
+
+
+    /** Remove observer for this object.
+     */
+    public void removeObserver( FieldObserver o ) {
+        if (observers != null) {
+            observers.remove(o);
+        }
+    }
+
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
+     */
+    public void update() {
+        if (observers != null) {
+            for (Iterator e = observers.iterator(); e.hasNext();) {
+                ((FieldObserver) e.next()).notify(this);
+            }
+        }
+    }
+
+
+    public String getInitValue() {
+        if (value != null) {
+            return value.toString();
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Return string representation close to declaration format,
+     * `public static final short MAX = 100', e.g..
+     *
+     * @return String representation of field
+     */
+    public final String toString() {
+        String name, signature, access; // Short cuts to constant pool
+        access = Utility.accessToString(access_flags);
+        access = access.equals("") ? "" : (access + " ");
+        signature = type.toString();
+        name = getName();
+        StringBuffer buf = new StringBuffer(32);
+        buf.append(access).append(signature).append(" ").append(name);
+        String value = getInitValue();
+        if (value != null) {
+            buf.append(" = ").append(value);
+        }
+        return buf.toString();
+    }
+
+
+    /** @return deep copy of this field
+     */
+    public FieldGen copy( ConstantPoolGen cp ) {
+        FieldGen fg = (FieldGen) clone();
+        fg.setConstantPool(cp);
+        return fg;
+    }
+
+
+    /**
+     * @return Comparison strategy object
+     */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two FieldGen objects are said to be equal when
+     * their names and signatures are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the field's name XOR signature.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FieldGenOrMethodGen.java b/java/org/apache/tomcat/util/bcel/generic/FieldGenOrMethodGen.java
new file mode 100644 (file)
index 0000000..f8c1e71
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.AccessFlags;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+
+/**
+ * Super class for FieldGen and MethodGen objects, since they have
+ * some methods in common!
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable {
+
+    protected String name;
+    protected Type type;
+    protected ConstantPoolGen cp;
+    private List attribute_vec = new ArrayList();
+    protected ArrayList       annotation_vec= new ArrayList();
+
+
+    protected FieldGenOrMethodGen() {
+    }
+
+
+    public void setType( Type type ) {
+        if (type.getType() == Constants.T_ADDRESS) {
+            throw new IllegalArgumentException("Type can not be " + type);
+        }
+        this.type = type;
+    }
+
+
+    public Type getType() {
+        return type;
+    }
+
+
+    /** @return name of method/field.
+     */
+    public String getName() {
+        return name;
+    }
+
+
+    public void setName( String name ) {
+        this.name = name;
+    }
+
+
+    public ConstantPoolGen getConstantPool() {
+        return cp;
+    }
+
+
+    public void setConstantPool( ConstantPoolGen cp ) {
+        this.cp = cp;
+    }
+
+
+    /**
+     * Add an attribute to this method. Currently, the JVM knows about
+     * the `Code', `ConstantValue', `Synthetic' and `Exceptions'
+     * attributes. Other attributes will be ignored by the JVM but do no
+     * harm.
+     *
+     * @param a attribute to be added
+     */
+    public void addAttribute( Attribute a ) {
+        attribute_vec.add(a);
+    }
+    
+    public void addAnnotationEntry(AnnotationEntryGen ag)
+       {
+               annotation_vec.add(ag);
+       }
+
+
+    /**
+     * Remove an attribute.
+     */
+    public void removeAttribute( Attribute a ) {
+        attribute_vec.remove(a);
+    }
+    
+    public void removeAnnotationEntry(AnnotationEntryGen ag)
+       {
+               annotation_vec.remove(ag);
+       }
+
+
+    /**
+     * Remove all attributes.
+     */
+    public void removeAttributes() {
+        attribute_vec.clear();
+    }
+    
+    public void removeAnnotationEntries()
+       {
+               annotation_vec.clear();
+       }
+
+
+    /**
+     * @return all attributes of this method.
+     */
+    public Attribute[] getAttributes() {
+        Attribute[] attributes = new Attribute[attribute_vec.size()];
+        attribute_vec.toArray(attributes);
+        return attributes;
+    }
+    
+    public AnnotationEntryGen[] getAnnotationEntries() {
+       AnnotationEntryGen[] annotations = new AnnotationEntryGen[annotation_vec.size()];
+       annotation_vec.toArray(annotations);
+       return annotations;
+      }
+
+
+    /** @return signature of method/field.
+     */
+    public abstract String getSignature();
+
+
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            System.err.println(e);
+            return null;
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FieldInstruction.java b/java/org/apache/tomcat/util/bcel/generic/FieldInstruction.java
new file mode 100644 (file)
index 0000000..b3a8707
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+
+/**
+ * Super class for the GET/PUTxxx family of instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class FieldInstruction extends FieldOrMethod implements TypedInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    FieldInstruction() {
+    }
+
+
+    /**
+     * @param index to constant pool
+     */
+    protected FieldInstruction(short opcode, int index) {
+        super(opcode, index);
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        return org.apache.tomcat.util.bcel.Constants.OPCODE_NAMES[opcode] + " "
+                + cp.constantToString(index, org.apache.tomcat.util.bcel.Constants.CONSTANT_Fieldref);
+    }
+
+
+    /** @return size of field (1 or 2)
+     */
+    protected int getFieldSize( ConstantPoolGen cpg ) {
+       return Type.getTypeSize(getSignature(cpg));
+    }
+
+
+    /** @return return type of referenced field
+     */
+    public Type getType( ConstantPoolGen cpg ) {
+        return getFieldType(cpg);
+    }
+
+
+    /** @return type of field
+     */
+    public Type getFieldType( ConstantPoolGen cpg ) {
+        return Type.getType(getSignature(cpg));
+    }
+
+
+    /** @return name of referenced field.
+     */
+    public String getFieldName( ConstantPoolGen cpg ) {
+        return getName(cpg);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FieldObserver.java b/java/org/apache/tomcat/util/bcel/generic/FieldObserver.java
new file mode 100644 (file)
index 0000000..da42468
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Imnplement this interface if you're interested in changes to a FieldGen object
+ * and register yourself with addObserver().
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface FieldObserver {
+
+    public void notify( FieldGen field );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/FieldOrMethod.java b/java/org/apache/tomcat/util/bcel/generic/FieldOrMethod.java
new file mode 100644 (file)
index 0000000..01d3b95
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.classfile.ConstantCP;
+import org.apache.tomcat.util.bcel.classfile.ConstantNameAndType;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+
+/**
+ * Super class for InvokeInstruction and FieldInstruction, since they have
+ * some methods in common!
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class FieldOrMethod extends CPInstruction implements LoadClass {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    FieldOrMethod() {
+    }
+
+
+    /**
+     * @param index to constant pool
+     */
+    protected FieldOrMethod(short opcode, int index) {
+        super(opcode, index);
+    }
+
+
+    /** @return signature of referenced method/field.
+     */
+    public String getSignature( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+        return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes();
+    }
+
+
+    /** @return name of referenced method/field.
+     */
+    public String getName( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
+        return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes();
+    }
+
+
+    /** @return name of the referenced class/interface
+     *  @deprecated If the instruction references an array class,
+     *    this method will return "java.lang.Object".
+     *    For code generated by Java 1.5, this answer is
+     *    sometimes wrong (e.g., if the "clone()" method is
+     *    called on an array).  A better idea is to use
+     *    the getReferenceType() method, which correctly distinguishes
+     *    between class types and array types.
+     */
+    public String getClassName( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+        String className = cp.getConstantString(cmr.getClassIndex(),
+                org.apache.tomcat.util.bcel.Constants.CONSTANT_Class);
+        if (className.startsWith("[")) {
+            // Turn array classes into java.lang.Object.
+            return "java.lang.Object";
+        }
+        return className.replace('/', '.');
+    }
+
+
+    /** @return type of the referenced class/interface
+     * @deprecated If the instruction references an array class,
+     *    the ObjectType returned will be invalid.  Use
+     *    getReferenceType() instead.
+     */
+    public ObjectType getClassType( ConstantPoolGen cpg ) {
+        return new ObjectType(getClassName(cpg));
+    }
+
+
+    /**
+     * Return the reference type representing the class, interface,
+     * or array class referenced by the instruction.
+     * @param cpg the ConstantPoolGen used to create the instruction
+     * @return an ObjectType (if the referenced class type is a class
+     *   or interface), or an ArrayType (if the referenced class
+     *   type is an array class)
+     */
+    public ReferenceType getReferenceType( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
+        String className = cp.getConstantString(cmr.getClassIndex(),
+                org.apache.tomcat.util.bcel.Constants.CONSTANT_Class);
+        if (className.startsWith("[")) {
+            return (ArrayType) Type.getType(className);
+        } else {
+            className = className.replace('/', '.');
+            return new ObjectType(className);
+        }
+    }
+
+
+    /** @return type of the referenced class/interface
+     */
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        return getClassType(cpg);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/GETFIELD.java b/java/org/apache/tomcat/util/bcel/generic/GETFIELD.java
new file mode 100644 (file)
index 0000000..22c29fd
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * GETFIELD - Fetch field from object
+ * <PRE>Stack: ..., objectref -&gt; ..., value</PRE>
+ * OR
+ * <PRE>Stack: ..., objectref -&gt; ..., value.word1, value.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer,
+        StackProducer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    GETFIELD() {
+    }
+
+
+    public GETFIELD(int index) {
+        super(Constants.GETFIELD, index);
+    }
+
+
+    public int produceStack( ConstantPoolGen cpg ) {
+        return getFieldSize(cpg);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitFieldInstruction(this);
+        v.visitGETFIELD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/GETSTATIC.java b/java/org/apache/tomcat/util/bcel/generic/GETSTATIC.java
new file mode 100644 (file)
index 0000000..aab6f17
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * GETSTATIC - Fetch static field from class
+ * <PRE>Stack: ..., -&gt; ..., value</PRE>
+ * OR
+ * <PRE>Stack: ..., -&gt; ..., value.word1, value.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    GETSTATIC() {
+    }
+
+
+    public GETSTATIC(int index) {
+        super(Constants.GETSTATIC, index);
+    }
+
+
+    public int produceStack( ConstantPoolGen cpg ) {
+        return getFieldSize(cpg);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitFieldInstruction(this);
+        v.visitGETSTATIC(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/GOTO.java b/java/org/apache/tomcat/util/bcel/generic/GOTO.java
new file mode 100644 (file)
index 0000000..f7484b5
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/** 
+ * GOTO - Branch always (to relative offset, not absolute address)
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class GOTO extends GotoInstruction implements VariableLengthInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    GOTO() {
+    }
+
+
+    public GOTO(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.GOTO, target);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        index = getTargetOffset();
+        if (opcode == org.apache.tomcat.util.bcel.Constants.GOTO) {
+            super.dump(out);
+        } else { // GOTO_W
+            index = getTargetOffset();
+            out.writeByte(opcode);
+            out.writeInt(index);
+        }
+    }
+
+
+    /** Called in pass 2 of InstructionList.setPositions() in order to update
+     * the branch target, that may shift due to variable length instructions.
+     */
+    protected int updatePosition( int offset, int max_offset ) {
+        int i = getTargetOffset(); // Depending on old position value
+        position += offset; // Position may be shifted by preceding expansions
+        if (Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate)
+            opcode = org.apache.tomcat.util.bcel.Constants.GOTO_W;
+            length = 5;
+            return 2; // 5 - 3
+        }
+        return 0;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitVariableLengthInstruction(this);
+        v.visitUnconditionalBranch(this);
+        v.visitBranchInstruction(this);
+        v.visitGotoInstruction(this);
+        v.visitGOTO(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/GOTO_W.java b/java/org/apache/tomcat/util/bcel/generic/GOTO_W.java
new file mode 100644 (file)
index 0000000..0e38a74
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * GOTO_W - Branch always (to relative offset, not absolute address)
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class GOTO_W extends GotoInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    GOTO_W() {
+    }
+
+
+    public GOTO_W(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.GOTO_W, target);
+        length = 5;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        index = getTargetOffset();
+        out.writeByte(opcode);
+        out.writeInt(index);
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        index = bytes.readInt();
+        length = 5;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitUnconditionalBranch(this);
+        v.visitBranchInstruction(this);
+        v.visitGotoInstruction(this);
+        v.visitGOTO_W(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/GotoInstruction.java b/java/org/apache/tomcat/util/bcel/generic/GotoInstruction.java
new file mode 100644 (file)
index 0000000..cd82eab
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * Super class for GOTO
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch {
+
+    GotoInstruction(short opcode, InstructionHandle target) {
+        super(opcode, target);
+    }
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    GotoInstruction() {
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2B.java b/java/org/apache/tomcat/util/bcel/generic/I2B.java
new file mode 100644 (file)
index 0000000..c7ca710
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * I2B - Convert int to byte
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2B extends ConversionInstruction {
+
+    /** Convert int to byte
+     */
+    public I2B() {
+        super(org.apache.tomcat.util.bcel.Constants.I2B);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2B(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2C.java b/java/org/apache/tomcat/util/bcel/generic/I2C.java
new file mode 100644 (file)
index 0000000..f6feaf2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * I2C - Convert int to char
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2C extends ConversionInstruction {
+
+    /** Convert int to char
+     */
+    public I2C() {
+        super(org.apache.tomcat.util.bcel.Constants.I2C);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2C(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2D.java b/java/org/apache/tomcat/util/bcel/generic/I2D.java
new file mode 100644 (file)
index 0000000..c1b8807
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * I2D - Convert int to double
+ * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2D extends ConversionInstruction {
+
+    /** Convert int to double
+     */
+    public I2D() {
+        super(org.apache.tomcat.util.bcel.Constants.I2D);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2D(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2F.java b/java/org/apache/tomcat/util/bcel/generic/I2F.java
new file mode 100644 (file)
index 0000000..e6d3b0c
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * I2F - Convert int to float
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2F extends ConversionInstruction {
+
+    /** Convert int to float
+     */
+    public I2F() {
+        super(org.apache.tomcat.util.bcel.Constants.I2F);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2F(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2L.java b/java/org/apache/tomcat/util/bcel/generic/I2L.java
new file mode 100644 (file)
index 0000000..df23b7d
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * I2L - Convert int to long
+ * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2L extends ConversionInstruction {
+
+    /** Convert int to long
+     */
+    public I2L() {
+        super(org.apache.tomcat.util.bcel.Constants.I2L);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2L(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/I2S.java b/java/org/apache/tomcat/util/bcel/generic/I2S.java
new file mode 100644 (file)
index 0000000..1c45254
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * I2S - Convert int to short
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class I2S extends ConversionInstruction {
+
+    public I2S() {
+        super(org.apache.tomcat.util.bcel.Constants.I2S);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitI2S(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IADD.java b/java/org/apache/tomcat/util/bcel/generic/IADD.java
new file mode 100644 (file)
index 0000000..48f0d85
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IADD - Add ints
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IADD extends ArithmeticInstruction {
+
+    /** Add ints
+     */
+    public IADD() {
+        super(org.apache.tomcat.util.bcel.Constants.IADD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIADD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IALOAD.java b/java/org/apache/tomcat/util/bcel/generic/IALOAD.java
new file mode 100644 (file)
index 0000000..9511a28
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IALOAD - Load int from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IALOAD extends ArrayInstruction implements StackProducer {
+
+    /** 
+     * Load int from array
+     */
+    public IALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.IALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitIALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IAND.java b/java/org/apache/tomcat/util/bcel/generic/IAND.java
new file mode 100644 (file)
index 0000000..10c240d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IAND - Bitwise AND int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IAND extends ArithmeticInstruction {
+
+    public IAND() {
+        super(org.apache.tomcat.util.bcel.Constants.IAND);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIAND(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IASTORE.java b/java/org/apache/tomcat/util/bcel/generic/IASTORE.java
new file mode 100644 (file)
index 0000000..1207d6e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IASTORE -  Store into int array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** 
+     * Store into int array
+     */
+    public IASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.IASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitIASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ICONST.java b/java/org/apache/tomcat/util/bcel/generic/ICONST.java
new file mode 100644 (file)
index 0000000..239570c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ICONST - Push value between -1, ..., 5, other values cause an exception
+ *
+ * <PRE>Stack: ... -&gt; ..., </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ICONST extends Instruction implements ConstantPushInstruction, TypedInstruction {
+
+    private int value;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ICONST() {
+    }
+
+
+    public ICONST(int i) {
+        super(org.apache.tomcat.util.bcel.Constants.ICONST_0, (short) 1);
+        if ((i >= -1) && (i <= 5)) {
+            opcode = (short) (org.apache.tomcat.util.bcel.Constants.ICONST_0 + i); // Even works for i == -1
+        } else {
+            throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + i);
+        }
+        value = i;
+    }
+
+
+    public Number getValue() {
+        return new Integer(value);
+    }
+
+
+    /** @return Type.INT
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.INT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitICONST(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IDIV.java b/java/org/apache/tomcat/util/bcel/generic/IDIV.java
new file mode 100644 (file)
index 0000000..ec999af
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * IDIV - Divide ints
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IDIV extends ArithmeticInstruction implements ExceptionThrower {
+
+    /** Divide ints
+     */
+    public IDIV() {
+        super(org.apache.tomcat.util.bcel.Constants.IDIV);
+    }
+
+
+    /** @return exceptions this instruction may cause
+     */
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIDIV(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFEQ.java b/java/org/apache/tomcat/util/bcel/generic/IFEQ.java
new file mode 100644 (file)
index 0000000..334ea9e
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFEQ - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFEQ extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFEQ() {
+    }
+
+
+    public IFEQ(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFEQ, target);
+    }
+
+
+    /**
+     * @return negation of instruction, e.g. IFEQ.negate() == IFNE
+     */
+    public IfInstruction negate() {
+        return new IFNE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFEQ(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFGE.java b/java/org/apache/tomcat/util/bcel/generic/IFGE.java
new file mode 100644 (file)
index 0000000..2fdb428
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFGE - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFGE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFGE() {
+    }
+
+
+    public IFGE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFGE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFLT(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFGE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFGT.java b/java/org/apache/tomcat/util/bcel/generic/IFGT.java
new file mode 100644 (file)
index 0000000..0d94ac7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFGT - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFGT extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFGT() {
+    }
+
+
+    public IFGT(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFGT, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFLE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFGT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFLE.java b/java/org/apache/tomcat/util/bcel/generic/IFLE.java
new file mode 100644 (file)
index 0000000..c59da8c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFLE - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFLE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFLE() {
+    }
+
+
+    public IFLE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFLE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFGT(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFLE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFLT.java b/java/org/apache/tomcat/util/bcel/generic/IFLT.java
new file mode 100644 (file)
index 0000000..560bf9b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFLT - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFLT extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFLT() {
+    }
+
+
+    public IFLT(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFLT, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFGE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFLT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFNE.java b/java/org/apache/tomcat/util/bcel/generic/IFNE.java
new file mode 100644 (file)
index 0000000..f32bb7f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFNE - Branch if int comparison with zero succeeds
+ *
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFNE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFNE() {
+    }
+
+
+    public IFNE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFNE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFEQ(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFNE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFNONNULL.java b/java/org/apache/tomcat/util/bcel/generic/IFNONNULL.java
new file mode 100644 (file)
index 0000000..1248d0d
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFNONNULL - Branch if reference is not null
+ *
+ * <PRE>Stack: ..., reference -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFNONNULL extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFNONNULL() {
+    }
+
+
+    public IFNONNULL(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFNONNULL, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFNULL(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFNONNULL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IFNULL.java b/java/org/apache/tomcat/util/bcel/generic/IFNULL.java
new file mode 100644 (file)
index 0000000..80e9387
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IFNULL - Branch if reference is not null
+ *
+ * <PRE>Stack: ..., reference -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IFNULL extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IFNULL() {
+    }
+
+
+    public IFNULL(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IFNULL, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IFNONNULL(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIFNULL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ACMPEQ.java b/java/org/apache/tomcat/util/bcel/generic/IF_ACMPEQ.java
new file mode 100644 (file)
index 0000000..8b05276
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ACMPEQ - Branch if reference comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ACMPEQ extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ACMPEQ() {
+    }
+
+
+    public IF_ACMPEQ(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ACMPEQ, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ACMPNE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ACMPEQ(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ACMPNE.java b/java/org/apache/tomcat/util/bcel/generic/IF_ACMPNE.java
new file mode 100644 (file)
index 0000000..02f821d
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ACMPNE - Branch if reference comparison doesn't succeed
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ACMPNE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ACMPNE() {
+    }
+
+
+    public IF_ACMPNE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ACMPNE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ACMPEQ(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ACMPNE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPEQ.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPEQ.java
new file mode 100644 (file)
index 0000000..b8822da
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPEQ - Branch if int comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPEQ extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPEQ() {
+    }
+
+
+    public IF_ICMPEQ(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPEQ, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPNE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPEQ(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPGE.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPGE.java
new file mode 100644 (file)
index 0000000..b24fd77
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPGE - Branch if int comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPGE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPGE() {
+    }
+
+
+    public IF_ICMPGE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPGE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPLT(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPGE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPGT.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPGT.java
new file mode 100644 (file)
index 0000000..580311c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPGT - Branch if int comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPGT extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPGT() {
+    }
+
+
+    public IF_ICMPGT(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPGT, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPLE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPGT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPLE.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPLE.java
new file mode 100644 (file)
index 0000000..1caa276
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPLE - Branch if int comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPLE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPLE() {
+    }
+
+
+    public IF_ICMPLE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPLE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPGT(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPLE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPLT.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPLT.java
new file mode 100644 (file)
index 0000000..b5cf633
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPLT - Branch if int comparison succeeds
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPLT extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPLT() {
+    }
+
+
+    public IF_ICMPLT(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPLT, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPGE(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPLT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IF_ICMPNE.java b/java/org/apache/tomcat/util/bcel/generic/IF_ICMPNE.java
new file mode 100644 (file)
index 0000000..5852e82
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IF_ICMPNE - Branch if int comparison doesn't succeed
+ *
+ * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IF_ICMPNE extends IfInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IF_ICMPNE() {
+    }
+
+
+    public IF_ICMPNE(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.IF_ICMPNE, target);
+    }
+
+
+    /**
+     * @return negation of instruction
+     */
+    public IfInstruction negate() {
+        return new IF_ICMPEQ(target);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitBranchInstruction(this);
+        v.visitIfInstruction(this);
+        v.visitIF_ICMPNE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IINC.java b/java/org/apache/tomcat/util/bcel/generic/IINC.java
new file mode 100644 (file)
index 0000000..4d62e1e
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/**
+ * IINC - Increment local variable by constant
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IINC extends LocalVariableInstruction {
+
+    private boolean wide;
+    private int c;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IINC() {
+    }
+
+
+    /**
+     * @param n index of local variable
+     * @param c increment factor
+     */
+    public IINC(int n, int c) {
+        super(); // Default behaviour of LocalVariableInstruction causes error
+        this.opcode = org.apache.tomcat.util.bcel.Constants.IINC;
+        this.length = (short) 3;
+        setIndex(n); // May set wide as side effect
+        setIncrement(c);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        if (wide) {
+            out.writeByte(org.apache.tomcat.util.bcel.Constants.WIDE);
+        }
+        out.writeByte(opcode);
+        if (wide) {
+            out.writeShort(n);
+            out.writeShort(c);
+        } else {
+            out.writeByte(n);
+            out.writeByte(c);
+        }
+    }
+
+
+    private final void setWide() {
+        wide = (n > org.apache.tomcat.util.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE);
+        if (wide) {
+            length = 6; // wide byte included  
+        } else {
+            length = 3;
+        }
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        this.wide = wide;
+        if (wide) {
+            length = 6;
+            n = bytes.readUnsignedShort();
+            c = bytes.readShort();
+        } else {
+            length = 3;
+            n = bytes.readUnsignedByte();
+            c = bytes.readByte();
+        }
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + c;
+    }
+
+
+    /**
+     * Set index of local variable.
+     */
+    public final void setIndex( int n ) {
+        if (n < 0) {
+            throw new ClassGenException("Negative index value: " + n);
+        }
+        this.n = n;
+        setWide();
+    }
+
+
+    /**
+     * @return increment factor
+     */
+    public final int getIncrement() {
+        return c;
+    }
+
+
+    /**
+     * Set increment factor.
+     */
+    public final void setIncrement( int c ) {
+        this.c = c;
+        setWide();
+    }
+
+
+    /** @return int type
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.INT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLocalVariableInstruction(this);
+        v.visitIINC(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ILOAD.java b/java/org/apache/tomcat/util/bcel/generic/ILOAD.java
new file mode 100644 (file)
index 0000000..404d6a4
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ILOAD - Load int from local variable onto stack
+ * <PRE>Stack: ... -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ILOAD extends LoadInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ILOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.ILOAD, org.apache.tomcat.util.bcel.Constants.ILOAD_0);
+    }
+
+
+    /** Load int from local variable
+     * @param n index of local variable
+     */
+    public ILOAD(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.ILOAD, org.apache.tomcat.util.bcel.Constants.ILOAD_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitILOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IMPDEP1.java b/java/org/apache/tomcat/util/bcel/generic/IMPDEP1.java
new file mode 100644 (file)
index 0000000..00d2b06
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * IMPDEP1 - Implementation dependent
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IMPDEP1 extends Instruction {
+
+    public IMPDEP1() {
+        super(org.apache.tomcat.util.bcel.Constants.IMPDEP1, (short) 1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitIMPDEP1(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IMPDEP2.java b/java/org/apache/tomcat/util/bcel/generic/IMPDEP2.java
new file mode 100644 (file)
index 0000000..7b110c1
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * IMPDEP2 - Implementation dependent
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IMPDEP2 extends Instruction {
+
+    public IMPDEP2() {
+        super(org.apache.tomcat.util.bcel.Constants.IMPDEP2, (short) 1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitIMPDEP2(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IMUL.java b/java/org/apache/tomcat/util/bcel/generic/IMUL.java
new file mode 100644 (file)
index 0000000..39e23c6
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IMUL - Multiply ints
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IMUL extends ArithmeticInstruction {
+
+    /** Multiply ints
+     */
+    public IMUL() {
+        super(org.apache.tomcat.util.bcel.Constants.IMUL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIMUL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INEG.java b/java/org/apache/tomcat/util/bcel/generic/INEG.java
new file mode 100644 (file)
index 0000000..33a23f0
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * INEG - Negate int
+ * <PRE>Stack: ..., value -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class INEG extends ArithmeticInstruction {
+
+    public INEG() {
+        super(org.apache.tomcat.util.bcel.Constants.INEG);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitINEG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INSTANCEOF.java b/java/org/apache/tomcat/util/bcel/generic/INSTANCEOF.java
new file mode 100644 (file)
index 0000000..061abf1
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * INSTANCEOF - Determine if object is of given type
+ * <PRE>Stack: ..., objectref -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower,
+        StackProducer, StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INSTANCEOF() {
+    }
+
+
+    public INSTANCEOF(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.INSTANCEOF, index);
+    }
+
+
+    public Class[] getExceptions() {
+        return org.apache.tomcat.util.bcel.ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION;
+    }
+
+
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        Type t = getType(cpg);
+        if (t instanceof ArrayType) {
+            t = ((ArrayType) t).getBasicType();
+        }
+        return (t instanceof ObjectType) ? (ObjectType) t : null;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLoadClass(this);
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitINSTANCEOF(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INVOKEINTERFACE.java b/java/org/apache/tomcat/util/bcel/generic/INVOKEINTERFACE.java
new file mode 100644 (file)
index 0000000..ae9fc81
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * INVOKEINTERFACE - Invoke interface method
+ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class INVOKEINTERFACE extends InvokeInstruction {
+
+    private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INVOKEINTERFACE() {
+    }
+
+
+    public INVOKEINTERFACE(int index, int nargs) {
+        super(Constants.INVOKEINTERFACE, index);
+        length = 5;
+        if (nargs < 1) {
+            throw new ClassGenException("Number of arguments must be > 0 " + nargs);
+        }
+        this.nargs = nargs;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        out.writeShort(index);
+        out.writeByte(nargs);
+        out.writeByte(0);
+    }
+
+
+    /**
+     * The <B>count</B> argument according to the Java Language Specification,
+     * Second Edition.
+     */
+    public int getCount() {
+        return nargs;
+    }
+
+
+    /**
+     * Read needed data (i.e., index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        super.initFromFile(bytes, wide);
+        length = 5;
+        nargs = bytes.readUnsignedByte();
+        bytes.readByte(); // Skip 0 byte
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        return super.toString(cp) + " " + nargs;
+    }
+
+
+    public int consumeStack( ConstantPoolGen cpg ) { // nargs is given in byte-code
+        return nargs; // nargs includes this reference
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitInvokeInstruction(this);
+        v.visitINVOKEINTERFACE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INVOKESPECIAL.java b/java/org/apache/tomcat/util/bcel/generic/INVOKESPECIAL.java
new file mode 100644 (file)
index 0000000..092e5e4
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * INVOKESPECIAL - Invoke instance method; special handling for superclass, private
+ * and instance initialization method invocations
+ *
+ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class INVOKESPECIAL extends InvokeInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INVOKESPECIAL() {
+    }
+
+
+    public INVOKESPECIAL(int index) {
+        super(Constants.INVOKESPECIAL, index);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitInvokeInstruction(this);
+        v.visitINVOKESPECIAL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INVOKESTATIC.java b/java/org/apache/tomcat/util/bcel/generic/INVOKESTATIC.java
new file mode 100644 (file)
index 0000000..3efbd95
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * INVOKESTATIC - Invoke a class (static) method
+ *
+ * <PRE>Stack: ..., [arg1, [arg2 ...]] -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class INVOKESTATIC extends InvokeInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INVOKESTATIC() {
+    }
+
+
+    public INVOKESTATIC(int index) {
+        super(Constants.INVOKESTATIC, index);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitInvokeInstruction(this);
+        v.visitINVOKESTATIC(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/INVOKEVIRTUAL.java b/java/org/apache/tomcat/util/bcel/generic/INVOKEVIRTUAL.java
new file mode 100644 (file)
index 0000000..4616936
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * INVOKEVIRTUAL - Invoke instance method; dispatch based on class
+ *
+ * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class INVOKEVIRTUAL extends InvokeInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INVOKEVIRTUAL() {
+    }
+
+
+    public INVOKEVIRTUAL(int index) {
+        super(Constants.INVOKEVIRTUAL, index);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[4 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 3] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitInvokeInstruction(this);
+        v.visitINVOKEVIRTUAL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IOR.java b/java/org/apache/tomcat/util/bcel/generic/IOR.java
new file mode 100644 (file)
index 0000000..d6cf5cd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IOR - Bitwise OR int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IOR extends ArithmeticInstruction {
+
+    public IOR() {
+        super(org.apache.tomcat.util.bcel.Constants.IOR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIOR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IREM.java b/java/org/apache/tomcat/util/bcel/generic/IREM.java
new file mode 100644 (file)
index 0000000..67b3cac
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * IREM - Remainder of int
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IREM extends ArithmeticInstruction implements ExceptionThrower {
+
+    /** Remainder of ints
+     */
+    public IREM() {
+        super(org.apache.tomcat.util.bcel.Constants.IREM);
+    }
+
+
+    /** @return exceptions this instruction may cause
+     */
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIREM(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IRETURN.java b/java/org/apache/tomcat/util/bcel/generic/IRETURN.java
new file mode 100644 (file)
index 0000000..e21b5ac
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IRETURN -  Return int from method
+ * <PRE>Stack: ..., value -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IRETURN extends ReturnInstruction {
+
+    /** Return int from method
+     */
+    public IRETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.IRETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitIRETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ISHL.java b/java/org/apache/tomcat/util/bcel/generic/ISHL.java
new file mode 100644 (file)
index 0000000..516dfb0
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * ISHL - Arithmetic shift left int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ISHL extends ArithmeticInstruction {
+
+    public ISHL() {
+        super(org.apache.tomcat.util.bcel.Constants.ISHL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitISHL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ISHR.java b/java/org/apache/tomcat/util/bcel/generic/ISHR.java
new file mode 100644 (file)
index 0000000..d8bbb01
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * ISHR - Arithmetic shift right int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ISHR extends ArithmeticInstruction {
+
+    public ISHR() {
+        super(org.apache.tomcat.util.bcel.Constants.ISHR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitISHR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ISTORE.java b/java/org/apache/tomcat/util/bcel/generic/ISTORE.java
new file mode 100644 (file)
index 0000000..f0a0ca1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ISTORE - Store int from stack into local variable
+ * <PRE>Stack: ..., value -&gt; ... </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ISTORE extends StoreInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ISTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.ISTORE, org.apache.tomcat.util.bcel.Constants.ISTORE_0);
+    }
+
+
+    /** Store int into local variable
+     * @param n index of local variable
+     */
+    public ISTORE(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.ISTORE, org.apache.tomcat.util.bcel.Constants.ISTORE_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitISTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ISUB.java b/java/org/apache/tomcat/util/bcel/generic/ISUB.java
new file mode 100644 (file)
index 0000000..67b5a66
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * ISUB - Substract ints
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ISUB extends ArithmeticInstruction {
+
+    /** Substract ints
+     */
+    public ISUB() {
+        super(org.apache.tomcat.util.bcel.Constants.ISUB);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitISUB(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IUSHR.java b/java/org/apache/tomcat/util/bcel/generic/IUSHR.java
new file mode 100644 (file)
index 0000000..f2bc5b4
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IUSHR - Logical shift right int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IUSHR extends ArithmeticInstruction {
+
+    public IUSHR() {
+        super(org.apache.tomcat.util.bcel.Constants.IUSHR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIUSHR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IXOR.java b/java/org/apache/tomcat/util/bcel/generic/IXOR.java
new file mode 100644 (file)
index 0000000..d898b16
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * IXOR - Bitwise XOR int
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class IXOR extends ArithmeticInstruction {
+
+    public IXOR() {
+        super(org.apache.tomcat.util.bcel.Constants.IXOR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitIXOR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IfInstruction.java b/java/org/apache/tomcat/util/bcel/generic/IfInstruction.java
new file mode 100644 (file)
index 0000000..df88950
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Super class for the IFxxx family of instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class IfInstruction extends BranchInstruction implements StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    IfInstruction() {
+    }
+
+
+    /**
+     * @param opcode opcode of instruction
+     * @param target Target instruction to branch to
+     */
+    protected IfInstruction(short opcode, InstructionHandle target) {
+        super(opcode, target);
+    }
+
+
+    /**
+     * @return negation of instruction, e.g. IFEQ.negate() == IFNE
+     */
+    public abstract IfInstruction negate();
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/IndexedInstruction.java b/java/org/apache/tomcat/util/bcel/generic/IndexedInstruction.java
new file mode 100644 (file)
index 0000000..be50d63
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote entity that refers to an index, e.g. local variable instructions,
+ * RET, CPInstruction, etc.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface IndexedInstruction {
+
+    public int getIndex();
+
+
+    public void setIndex( int index );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/Instruction.java b/java/org/apache/tomcat/util/bcel/generic/Instruction.java
new file mode 100644 (file)
index 0000000..e294bf7
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Locale;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * Abstract super class for all Java byte codes.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class Instruction implements Cloneable, Serializable {
+
+    protected short length = 1; // Length of instruction in bytes 
+    protected short opcode = -1; // Opcode number
+    private static InstructionComparator cmp = InstructionComparator.DEFAULT;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    Instruction() {
+    }
+
+
+    public Instruction(short opcode, short length) {
+        this.length = length;
+        this.opcode = opcode;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode); // Common for all instructions
+    }
+
+
+    /** @return name of instruction, i.e., opcode name
+     */
+    public String getName() {
+        return Constants.OPCODE_NAMES[opcode];
+    }
+
+
+    /**
+     * Long output format:
+     *
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" 
+     * "("&lt;length of instruction&gt;")"
+     *
+     * @param verbose long/short format switch
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        if (verbose) {
+            return getName() + "[" + opcode + "](" + length + ")";
+        } else {
+            return getName();
+        }
+    }
+
+
+    /**
+     * @return mnemonic for instruction in verbose format
+     */
+    public String toString() {
+        return toString(true);
+    }
+
+
+    /**
+     * @return mnemonic for instruction with sumbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        return toString(false);
+    }
+
+
+    /**
+     * Use with caution, since `BranchInstruction's have a `target' reference which
+     * is not copied correctly (only basic types are). This also applies for 
+     * `Select' instructions with their multiple branch targets.
+     *
+     * @see BranchInstruction
+     * @return (shallow) copy of an instruction
+     */
+    public Instruction copy() {
+        Instruction i = null;
+        // "Constant" instruction, no need to duplicate
+        if (InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) {
+            i = this;
+        } else {
+            try {
+                i = (Instruction) clone();
+            } catch (CloneNotSupportedException e) {
+                System.err.println(e);
+            }
+        }
+        return i;
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     *
+     * @param bytes byte sequence to read from
+     * @param wide "wide" instruction flag
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+    }
+
+
+    /**
+     * Read an instruction from (byte code) input stream and return the
+     * appropiate object.
+     *
+     * @param bytes input stream bytes
+     * @return instruction object being read
+     */
+    public static final Instruction readInstruction( ByteSequence bytes ) throws IOException {
+        boolean wide = false;
+        short opcode = (short) bytes.readUnsignedByte();
+        Instruction obj = null;
+        if (opcode == Constants.WIDE) { // Read next opcode after wide byte
+            wide = true;
+            opcode = (short) bytes.readUnsignedByte();
+        }
+        if (InstructionConstants.INSTRUCTIONS[opcode] != null) {
+            return InstructionConstants.INSTRUCTIONS[opcode]; // Used predefined immutable object, if available
+        }
+        
+        switch (opcode) {
+                       case Constants.BIPUSH:
+                               obj = new BIPUSH();
+                               break;
+                       case Constants.SIPUSH:
+                               obj = new SIPUSH();
+                               break;
+                       case Constants.LDC:
+                               obj = new LDC();
+                               break;
+                       case Constants.LDC_W:
+                               obj = new LDC_W();
+                               break;
+                       case Constants.LDC2_W:
+                               obj = new LDC2_W();
+                               break;
+                       case Constants.ILOAD:
+                               obj = new ILOAD();
+                               break;
+                       case Constants.LLOAD:
+                               obj = new LLOAD();
+                               break;
+                       case Constants.FLOAD:
+                               obj = new FLOAD();
+                               break;
+                       case Constants.DLOAD:
+                               obj = new DLOAD();
+                               break;
+                       case Constants.ALOAD:
+                               obj = new ALOAD();
+                               break;
+                       case Constants.ILOAD_0:
+                               obj = new ILOAD(0);
+                               break;
+                       case Constants.ILOAD_1:
+                               obj = new ILOAD(1);
+                               break;
+                       case Constants.ILOAD_2:
+                               obj = new ILOAD(2);
+                               break;
+                       case Constants.ILOAD_3:
+                               obj = new ILOAD(3);
+                               break;
+                       case Constants.LLOAD_0:
+                               obj = new LLOAD(0);
+                               break;
+                       case Constants.LLOAD_1:
+                               obj = new LLOAD(1);
+                               break;
+                       case Constants.LLOAD_2:
+                               obj = new LLOAD(2);
+                               break;
+                       case Constants.LLOAD_3:
+                               obj = new LLOAD(3);
+                               break;
+                       case Constants.FLOAD_0:
+                               obj = new FLOAD(0);
+                               break;
+                       case Constants.FLOAD_1:
+                               obj = new FLOAD(1);
+                               break;
+                       case Constants.FLOAD_2:
+                               obj = new FLOAD(2);
+                               break;
+                       case Constants.FLOAD_3:
+                               obj = new FLOAD(3);
+                               break;
+                       case Constants.DLOAD_0:
+                               obj = new DLOAD(0);
+                               break;
+                       case Constants.DLOAD_1:
+                               obj = new DLOAD(1);
+                               break;
+                       case Constants.DLOAD_2:
+                               obj = new DLOAD(2);
+                               break;
+                       case Constants.DLOAD_3:
+                               obj = new DLOAD(3);
+                               break;
+                       case Constants.ALOAD_0:
+                               obj = new ALOAD(0);
+                               break;
+                       case Constants.ALOAD_1:
+                               obj = new ALOAD(1);
+                               break;
+                       case Constants.ALOAD_2:
+                               obj = new ALOAD(2);
+                               break;
+                       case Constants.ALOAD_3:
+                               obj = new ALOAD(3);
+                               break;
+                       case Constants.ISTORE:
+                               obj = new ISTORE();
+                               break;
+                       case Constants.LSTORE:
+                               obj = new LSTORE();
+                               break;
+                       case Constants.FSTORE:
+                               obj = new FSTORE();
+                               break;
+                       case Constants.DSTORE:
+                               obj = new DSTORE();
+                               break;
+                       case Constants.ASTORE:
+                               obj = new ASTORE();
+                               break;
+                       case Constants.ISTORE_0:
+                               obj = new ISTORE(0);
+                               break;
+                       case Constants.ISTORE_1:
+                               obj = new ISTORE(1);
+                               break;
+                       case Constants.ISTORE_2:
+                               obj = new ISTORE(2);
+                               break;
+                       case Constants.ISTORE_3:
+                               obj = new ISTORE(3);
+                               break;
+                       case Constants.LSTORE_0:
+                               obj = new LSTORE(0);
+                               break;
+                       case Constants.LSTORE_1:
+                               obj = new LSTORE(1);
+                               break;
+                       case Constants.LSTORE_2:
+                               obj = new LSTORE(2);
+                               break;
+                       case Constants.LSTORE_3:
+                               obj = new LSTORE(3);
+                               break;
+                       case Constants.FSTORE_0:
+                               obj = new FSTORE(0);
+                               break;
+                       case Constants.FSTORE_1:
+                               obj = new FSTORE(1);
+                               break;
+                       case Constants.FSTORE_2:
+                               obj = new FSTORE(2);
+                               break;
+                       case Constants.FSTORE_3:
+                               obj = new FSTORE(3);
+                               break;
+                       case Constants.DSTORE_0:
+                               obj = new DSTORE(0);
+                               break;
+                       case Constants.DSTORE_1:
+                               obj = new DSTORE(1);
+                               break;
+                       case Constants.DSTORE_2:
+                               obj = new DSTORE(2);
+                               break;
+                       case Constants.DSTORE_3:
+                               obj = new DSTORE(3);
+                               break;
+                       case Constants.ASTORE_0:
+                               obj = new ASTORE(0);
+                               break;
+                       case Constants.ASTORE_1:
+                               obj = new ASTORE(1);
+                               break;
+                       case Constants.ASTORE_2:
+                               obj = new ASTORE(2);
+                               break;
+                       case Constants.ASTORE_3:
+                               obj = new ASTORE(3);
+                               break;
+                       case Constants.IINC:
+                               obj = new IINC();
+                               break;
+                       case Constants.IFEQ:
+                               obj = new IFEQ();
+                               break;
+                       case Constants.IFNE:
+                               obj = new IFNE();
+                               break;
+                       case Constants.IFLT:
+                               obj = new IFLT();
+                               break;
+                       case Constants.IFGE:
+                               obj = new IFGE();
+                               break;
+                       case Constants.IFGT:
+                               obj = new IFGT();
+                               break;
+                       case Constants.IFLE:
+                               obj = new IFLE();
+                               break;
+                       case Constants.IF_ICMPEQ:
+                               obj = new IF_ICMPEQ();
+                               break;
+                       case Constants.IF_ICMPNE:
+                               obj = new IF_ICMPNE();
+                               break;
+                       case Constants.IF_ICMPLT:
+                               obj = new IF_ICMPLT();
+                               break;
+                       case Constants.IF_ICMPGE:
+                               obj = new IF_ICMPGE();
+                               break;
+                       case Constants.IF_ICMPGT:
+                               obj = new IF_ICMPGT();
+                               break;
+                       case Constants.IF_ICMPLE:
+                               obj = new IF_ICMPLE();
+                               break;
+                       case Constants.IF_ACMPEQ:
+                               obj = new IF_ACMPEQ();
+                               break;
+                       case Constants.IF_ACMPNE:
+                               obj = new IF_ACMPNE();
+                               break;
+                       case Constants.GOTO:
+                               obj = new GOTO();
+                               break;
+                       case Constants.JSR:
+                               obj = new JSR();
+                               break;
+                       case Constants.RET:
+                               obj = new RET();
+                               break;
+                       case Constants.TABLESWITCH:
+                               obj = new TABLESWITCH();
+                               break;
+                       case Constants.LOOKUPSWITCH:
+                               obj = new LOOKUPSWITCH();
+                               break;
+                       case Constants.GETSTATIC:
+                               obj = new GETSTATIC();
+                               break;
+                       case Constants.PUTSTATIC:
+                               obj = new PUTSTATIC();
+                               break;
+                       case Constants.GETFIELD:
+                               obj = new GETFIELD();
+                               break;
+                       case Constants.PUTFIELD:
+                               obj = new PUTFIELD();
+                               break;
+                       case Constants.INVOKEVIRTUAL:
+                               obj = new INVOKEVIRTUAL();
+                               break;
+                       case Constants.INVOKESPECIAL:
+                               obj = new INVOKESPECIAL();
+                               break;
+                       case Constants.INVOKESTATIC:
+                               obj = new INVOKESTATIC();
+                               break;
+                       case Constants.INVOKEINTERFACE:
+                               obj = new INVOKEINTERFACE();
+                               break;
+                       case Constants.NEW:
+                               obj = new NEW();
+                               break;
+                       case Constants.NEWARRAY:
+                               obj = new NEWARRAY();
+                               break;
+                       case Constants.ANEWARRAY:
+                               obj = new ANEWARRAY();
+                               break;
+                       case Constants.CHECKCAST:
+                               obj = new CHECKCAST();
+                               break;
+                       case Constants.INSTANCEOF:
+                               obj = new INSTANCEOF();
+                               break;
+                       case Constants.MULTIANEWARRAY:
+                               obj = new MULTIANEWARRAY();
+                               break;
+                       case Constants.IFNULL:
+                               obj = new IFNULL();
+                               break;
+                       case Constants.IFNONNULL:
+                               obj = new IFNONNULL();
+                               break;
+                       case Constants.GOTO_W:
+                               obj = new GOTO_W();
+                               break;
+                       case Constants.JSR_W:
+                               obj = new JSR_W();
+                               break;
+                       case Constants.BREAKPOINT:
+                               obj = new BREAKPOINT();
+                               break;
+                       case Constants.IMPDEP1:
+                               obj = new IMPDEP1();
+                               break;
+                       case Constants.IMPDEP2:
+                               obj = new IMPDEP2();
+                               break;
+                       default:
+                               throw new ClassGenException("Illegal opcode detected: " + opcode);
+
+               }
+        
+        if (wide
+                               && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) {
+                       throw new ClassGenException("Illegal opcode after wide: " + opcode);
+               }
+               obj.setOpcode(opcode);
+               obj.initFromFile(bytes, wide); // Do further initializations, if any
+               return obj;
+       }
+
+    /**
+     * This method also gives right results for instructions whose
+     * effect on the stack depends on the constant pool entry they
+     * reference.
+     *  @return Number of words consumed from stack by this instruction,
+     * or Constants.UNPREDICTABLE, if this can not be computed statically
+     */
+    public int consumeStack( ConstantPoolGen cpg ) {
+        return Constants.CONSUME_STACK[opcode];
+    }
+
+
+    /**
+     * This method also gives right results for instructions whose
+     * effect on the stack depends on the constant pool entry they
+     * reference.
+     * @return Number of words produced onto stack by this instruction,
+     * or Constants.UNPREDICTABLE, if this can not be computed statically
+     */
+    public int produceStack( ConstantPoolGen cpg ) {
+        return Constants.PRODUCE_STACK[opcode];
+    }
+
+
+    /**
+     * @return this instructions opcode
+     */
+    public short getOpcode() {
+        return opcode;
+    }
+
+
+    /**
+     * @return length (in bytes) of instruction
+     */
+    public int getLength() {
+        return length;
+    }
+
+
+    /**
+     * Needed in readInstruction.
+     */
+    private void setOpcode( short opcode ) {
+        this.opcode = opcode;
+    }
+
+
+    /** Some instructions may be reused, so don't do anything by default.
+     */
+    void dispose() {
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public abstract void accept( Visitor v );
+
+
+    /** Get Comparator object used in the equals() method to determine
+     * equality of instructions.
+     *
+     * @return currently used comparator for equals()
+     */
+    public static InstructionComparator getComparator() {
+        return cmp;
+    }
+
+
+    /** Set comparator to be used for equals().
+     */
+    public static void setComparator( InstructionComparator c ) {
+        cmp = c;
+    }
+
+
+    /** Check for equality, delegated to comparator
+     * @return true if that is an Instruction and has the same opcode
+     */
+    public boolean equals( Object that ) {
+        return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionComparator.java b/java/org/apache/tomcat/util/bcel/generic/InstructionComparator.java
new file mode 100644 (file)
index 0000000..71bac69
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Equality of instructions isn't clearly to be defined. You might
+ * wish, for example, to compare whether instructions have the same
+ * meaning. E.g., whether two INVOKEVIRTUALs describe the same
+ * call.<br>The DEFAULT comparator however, considers two instructions
+ * to be equal if they have same opcode and point to the same indexes
+ * (if any) in the constant pool or the same local variable index. Branch
+ * instructions must have the same target.
+ *
+ * @see Instruction
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface InstructionComparator {
+
+    public static final InstructionComparator DEFAULT = new InstructionComparator() {
+
+        public boolean equals( Instruction i1, Instruction i2 ) {
+            if (i1.opcode == i2.opcode) {
+                if (i1 instanceof Select) {
+                    InstructionHandle[] t1 = ((Select) i1).getTargets();
+                    InstructionHandle[] t2 = ((Select) i2).getTargets();
+                    if (t1.length == t2.length) {
+                        for (int i = 0; i < t1.length; i++) {
+                            if (t1[i] != t2[i]) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+                } else if (i1 instanceof BranchInstruction) {
+                    return ((BranchInstruction) i1).target == ((BranchInstruction) i2).target;
+                } else if (i1 instanceof ConstantPushInstruction) {
+                    return ((ConstantPushInstruction) i1).getValue().equals(
+                            ((ConstantPushInstruction) i2).getValue());
+                } else if (i1 instanceof IndexedInstruction) {
+                    return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2)
+                            .getIndex();
+                } else if (i1 instanceof NEWARRAY) {
+                    return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2).getTypecode();
+                } else {
+                    return true;
+                }
+            }
+            return false;
+        }
+    };
+
+
+    public boolean equals( Instruction i1, Instruction i2 );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionConstants.java b/java/org/apache/tomcat/util/bcel/generic/InstructionConstants.java
new file mode 100644 (file)
index 0000000..817015a
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * This interface contains shareable instruction objects.
+ *
+ * In order to save memory you can use some instructions multiply,
+ * since they have an immutable state and are directly derived from
+ * Instruction.  I.e. they have no instance fields that could be
+ * changed. Since some of these instructions like ICONST_0 occur
+ * very frequently this can save a lot of time and space. This
+ * feature is an adaptation of the FlyWeight design pattern, we
+ * just use an array instead of a factory.
+ *
+ * The Instructions can also accessed directly under their names, so
+ * it's possible to write il.append(Instruction.ICONST_0);
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface InstructionConstants {
+
+    /** Predefined instruction objects
+     */
+    public static final Instruction NOP = new NOP();
+    public static final Instruction ACONST_NULL = new ACONST_NULL();
+    public static final Instruction ICONST_M1 = new ICONST(-1);
+    public static final Instruction ICONST_0 = new ICONST(0);
+    public static final Instruction ICONST_1 = new ICONST(1);
+    public static final Instruction ICONST_2 = new ICONST(2);
+    public static final Instruction ICONST_3 = new ICONST(3);
+    public static final Instruction ICONST_4 = new ICONST(4);
+    public static final Instruction ICONST_5 = new ICONST(5);
+    public static final Instruction LCONST_0 = new LCONST(0);
+    public static final Instruction LCONST_1 = new LCONST(1);
+    public static final Instruction FCONST_0 = new FCONST(0);
+    public static final Instruction FCONST_1 = new FCONST(1);
+    public static final Instruction FCONST_2 = new FCONST(2);
+    public static final Instruction DCONST_0 = new DCONST(0);
+    public static final Instruction DCONST_1 = new DCONST(1);
+    public static final ArrayInstruction IALOAD = new IALOAD();
+    public static final ArrayInstruction LALOAD = new LALOAD();
+    public static final ArrayInstruction FALOAD = new FALOAD();
+    public static final ArrayInstruction DALOAD = new DALOAD();
+    public static final ArrayInstruction AALOAD = new AALOAD();
+    public static final ArrayInstruction BALOAD = new BALOAD();
+    public static final ArrayInstruction CALOAD = new CALOAD();
+    public static final ArrayInstruction SALOAD = new SALOAD();
+    public static final ArrayInstruction IASTORE = new IASTORE();
+    public static final ArrayInstruction LASTORE = new LASTORE();
+    public static final ArrayInstruction FASTORE = new FASTORE();
+    public static final ArrayInstruction DASTORE = new DASTORE();
+    public static final ArrayInstruction AASTORE = new AASTORE();
+    public static final ArrayInstruction BASTORE = new BASTORE();
+    public static final ArrayInstruction CASTORE = new CASTORE();
+    public static final ArrayInstruction SASTORE = new SASTORE();
+    public static final StackInstruction POP = new POP();
+    public static final StackInstruction POP2 = new POP2();
+    public static final StackInstruction DUP = new DUP();
+    public static final StackInstruction DUP_X1 = new DUP_X1();
+    public static final StackInstruction DUP_X2 = new DUP_X2();
+    public static final StackInstruction DUP2 = new DUP2();
+    public static final StackInstruction DUP2_X1 = new DUP2_X1();
+    public static final StackInstruction DUP2_X2 = new DUP2_X2();
+    public static final StackInstruction SWAP = new SWAP();
+    public static final ArithmeticInstruction IADD = new IADD();
+    public static final ArithmeticInstruction LADD = new LADD();
+    public static final ArithmeticInstruction FADD = new FADD();
+    public static final ArithmeticInstruction DADD = new DADD();
+    public static final ArithmeticInstruction ISUB = new ISUB();
+    public static final ArithmeticInstruction LSUB = new LSUB();
+    public static final ArithmeticInstruction FSUB = new FSUB();
+    public static final ArithmeticInstruction DSUB = new DSUB();
+    public static final ArithmeticInstruction IMUL = new IMUL();
+    public static final ArithmeticInstruction LMUL = new LMUL();
+    public static final ArithmeticInstruction FMUL = new FMUL();
+    public static final ArithmeticInstruction DMUL = new DMUL();
+    public static final ArithmeticInstruction IDIV = new IDIV();
+    public static final ArithmeticInstruction LDIV = new LDIV();
+    public static final ArithmeticInstruction FDIV = new FDIV();
+    public static final ArithmeticInstruction DDIV = new DDIV();
+    public static final ArithmeticInstruction IREM = new IREM();
+    public static final ArithmeticInstruction LREM = new LREM();
+    public static final ArithmeticInstruction FREM = new FREM();
+    public static final ArithmeticInstruction DREM = new DREM();
+    public static final ArithmeticInstruction INEG = new INEG();
+    public static final ArithmeticInstruction LNEG = new LNEG();
+    public static final ArithmeticInstruction FNEG = new FNEG();
+    public static final ArithmeticInstruction DNEG = new DNEG();
+    public static final ArithmeticInstruction ISHL = new ISHL();
+    public static final ArithmeticInstruction LSHL = new LSHL();
+    public static final ArithmeticInstruction ISHR = new ISHR();
+    public static final ArithmeticInstruction LSHR = new LSHR();
+    public static final ArithmeticInstruction IUSHR = new IUSHR();
+    public static final ArithmeticInstruction LUSHR = new LUSHR();
+    public static final ArithmeticInstruction IAND = new IAND();
+    public static final ArithmeticInstruction LAND = new LAND();
+    public static final ArithmeticInstruction IOR = new IOR();
+    public static final ArithmeticInstruction LOR = new LOR();
+    public static final ArithmeticInstruction IXOR = new IXOR();
+    public static final ArithmeticInstruction LXOR = new LXOR();
+    public static final ConversionInstruction I2L = new I2L();
+    public static final ConversionInstruction I2F = new I2F();
+    public static final ConversionInstruction I2D = new I2D();
+    public static final ConversionInstruction L2I = new L2I();
+    public static final ConversionInstruction L2F = new L2F();
+    public static final ConversionInstruction L2D = new L2D();
+    public static final ConversionInstruction F2I = new F2I();
+    public static final ConversionInstruction F2L = new F2L();
+    public static final ConversionInstruction F2D = new F2D();
+    public static final ConversionInstruction D2I = new D2I();
+    public static final ConversionInstruction D2L = new D2L();
+    public static final ConversionInstruction D2F = new D2F();
+    public static final ConversionInstruction I2B = new I2B();
+    public static final ConversionInstruction I2C = new I2C();
+    public static final ConversionInstruction I2S = new I2S();
+    public static final Instruction LCMP = new LCMP();
+    public static final Instruction FCMPL = new FCMPL();
+    public static final Instruction FCMPG = new FCMPG();
+    public static final Instruction DCMPL = new DCMPL();
+    public static final Instruction DCMPG = new DCMPG();
+    public static final ReturnInstruction IRETURN = new IRETURN();
+    public static final ReturnInstruction LRETURN = new LRETURN();
+    public static final ReturnInstruction FRETURN = new FRETURN();
+    public static final ReturnInstruction DRETURN = new DRETURN();
+    public static final ReturnInstruction ARETURN = new ARETURN();
+    public static final ReturnInstruction RETURN = new RETURN();
+    public static final Instruction ARRAYLENGTH = new ARRAYLENGTH();
+    public static final Instruction ATHROW = new ATHROW();
+    public static final Instruction MONITORENTER = new MONITORENTER();
+    public static final Instruction MONITOREXIT = new MONITOREXIT();
+    /** You can use these constants in multiple places safely, if you can guarantee
+     * that you will never alter their internal values, e.g. call setIndex().
+     */
+    public static final LocalVariableInstruction THIS = new ALOAD(0);
+    public static final LocalVariableInstruction ALOAD_0 = THIS;
+    public static final LocalVariableInstruction ALOAD_1 = new ALOAD(1);
+    public static final LocalVariableInstruction ALOAD_2 = new ALOAD(2);
+    public static final LocalVariableInstruction ILOAD_0 = new ILOAD(0);
+    public static final LocalVariableInstruction ILOAD_1 = new ILOAD(1);
+    public static final LocalVariableInstruction ILOAD_2 = new ILOAD(2);
+    public static final LocalVariableInstruction ASTORE_0 = new ASTORE(0);
+    public static final LocalVariableInstruction ASTORE_1 = new ASTORE(1);
+    public static final LocalVariableInstruction ASTORE_2 = new ASTORE(2);
+    public static final LocalVariableInstruction ISTORE_0 = new ISTORE(0);
+    public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1);
+    public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2);
+    /** Get object via its opcode, for immutable instructions like
+     * branch instructions entries are set to null.
+     */
+    public static final Instruction[] INSTRUCTIONS = new Instruction[256];
+    /** Interfaces may have no static initializers, so we simulate this
+     * with an inner class.
+     */
+    static final Clinit bla = new Clinit();
+
+    static class Clinit {
+
+        Clinit() {
+            INSTRUCTIONS[Constants.NOP] = NOP;
+            INSTRUCTIONS[Constants.ACONST_NULL] = ACONST_NULL;
+            INSTRUCTIONS[Constants.ICONST_M1] = ICONST_M1;
+            INSTRUCTIONS[Constants.ICONST_0] = ICONST_0;
+            INSTRUCTIONS[Constants.ICONST_1] = ICONST_1;
+            INSTRUCTIONS[Constants.ICONST_2] = ICONST_2;
+            INSTRUCTIONS[Constants.ICONST_3] = ICONST_3;
+            INSTRUCTIONS[Constants.ICONST_4] = ICONST_4;
+            INSTRUCTIONS[Constants.ICONST_5] = ICONST_5;
+            INSTRUCTIONS[Constants.LCONST_0] = LCONST_0;
+            INSTRUCTIONS[Constants.LCONST_1] = LCONST_1;
+            INSTRUCTIONS[Constants.FCONST_0] = FCONST_0;
+            INSTRUCTIONS[Constants.FCONST_1] = FCONST_1;
+            INSTRUCTIONS[Constants.FCONST_2] = FCONST_2;
+            INSTRUCTIONS[Constants.DCONST_0] = DCONST_0;
+            INSTRUCTIONS[Constants.DCONST_1] = DCONST_1;
+            INSTRUCTIONS[Constants.IALOAD] = IALOAD;
+            INSTRUCTIONS[Constants.LALOAD] = LALOAD;
+            INSTRUCTIONS[Constants.FALOAD] = FALOAD;
+            INSTRUCTIONS[Constants.DALOAD] = DALOAD;
+            INSTRUCTIONS[Constants.AALOAD] = AALOAD;
+            INSTRUCTIONS[Constants.BALOAD] = BALOAD;
+            INSTRUCTIONS[Constants.CALOAD] = CALOAD;
+            INSTRUCTIONS[Constants.SALOAD] = SALOAD;
+            INSTRUCTIONS[Constants.IASTORE] = IASTORE;
+            INSTRUCTIONS[Constants.LASTORE] = LASTORE;
+            INSTRUCTIONS[Constants.FASTORE] = FASTORE;
+            INSTRUCTIONS[Constants.DASTORE] = DASTORE;
+            INSTRUCTIONS[Constants.AASTORE] = AASTORE;
+            INSTRUCTIONS[Constants.BASTORE] = BASTORE;
+            INSTRUCTIONS[Constants.CASTORE] = CASTORE;
+            INSTRUCTIONS[Constants.SASTORE] = SASTORE;
+            INSTRUCTIONS[Constants.POP] = POP;
+            INSTRUCTIONS[Constants.POP2] = POP2;
+            INSTRUCTIONS[Constants.DUP] = DUP;
+            INSTRUCTIONS[Constants.DUP_X1] = DUP_X1;
+            INSTRUCTIONS[Constants.DUP_X2] = DUP_X2;
+            INSTRUCTIONS[Constants.DUP2] = DUP2;
+            INSTRUCTIONS[Constants.DUP2_X1] = DUP2_X1;
+            INSTRUCTIONS[Constants.DUP2_X2] = DUP2_X2;
+            INSTRUCTIONS[Constants.SWAP] = SWAP;
+            INSTRUCTIONS[Constants.IADD] = IADD;
+            INSTRUCTIONS[Constants.LADD] = LADD;
+            INSTRUCTIONS[Constants.FADD] = FADD;
+            INSTRUCTIONS[Constants.DADD] = DADD;
+            INSTRUCTIONS[Constants.ISUB] = ISUB;
+            INSTRUCTIONS[Constants.LSUB] = LSUB;
+            INSTRUCTIONS[Constants.FSUB] = FSUB;
+            INSTRUCTIONS[Constants.DSUB] = DSUB;
+            INSTRUCTIONS[Constants.IMUL] = IMUL;
+            INSTRUCTIONS[Constants.LMUL] = LMUL;
+            INSTRUCTIONS[Constants.FMUL] = FMUL;
+            INSTRUCTIONS[Constants.DMUL] = DMUL;
+            INSTRUCTIONS[Constants.IDIV] = IDIV;
+            INSTRUCTIONS[Constants.LDIV] = LDIV;
+            INSTRUCTIONS[Constants.FDIV] = FDIV;
+            INSTRUCTIONS[Constants.DDIV] = DDIV;
+            INSTRUCTIONS[Constants.IREM] = IREM;
+            INSTRUCTIONS[Constants.LREM] = LREM;
+            INSTRUCTIONS[Constants.FREM] = FREM;
+            INSTRUCTIONS[Constants.DREM] = DREM;
+            INSTRUCTIONS[Constants.INEG] = INEG;
+            INSTRUCTIONS[Constants.LNEG] = LNEG;
+            INSTRUCTIONS[Constants.FNEG] = FNEG;
+            INSTRUCTIONS[Constants.DNEG] = DNEG;
+            INSTRUCTIONS[Constants.ISHL] = ISHL;
+            INSTRUCTIONS[Constants.LSHL] = LSHL;
+            INSTRUCTIONS[Constants.ISHR] = ISHR;
+            INSTRUCTIONS[Constants.LSHR] = LSHR;
+            INSTRUCTIONS[Constants.IUSHR] = IUSHR;
+            INSTRUCTIONS[Constants.LUSHR] = LUSHR;
+            INSTRUCTIONS[Constants.IAND] = IAND;
+            INSTRUCTIONS[Constants.LAND] = LAND;
+            INSTRUCTIONS[Constants.IOR] = IOR;
+            INSTRUCTIONS[Constants.LOR] = LOR;
+            INSTRUCTIONS[Constants.IXOR] = IXOR;
+            INSTRUCTIONS[Constants.LXOR] = LXOR;
+            INSTRUCTIONS[Constants.I2L] = I2L;
+            INSTRUCTIONS[Constants.I2F] = I2F;
+            INSTRUCTIONS[Constants.I2D] = I2D;
+            INSTRUCTIONS[Constants.L2I] = L2I;
+            INSTRUCTIONS[Constants.L2F] = L2F;
+            INSTRUCTIONS[Constants.L2D] = L2D;
+            INSTRUCTIONS[Constants.F2I] = F2I;
+            INSTRUCTIONS[Constants.F2L] = F2L;
+            INSTRUCTIONS[Constants.F2D] = F2D;
+            INSTRUCTIONS[Constants.D2I] = D2I;
+            INSTRUCTIONS[Constants.D2L] = D2L;
+            INSTRUCTIONS[Constants.D2F] = D2F;
+            INSTRUCTIONS[Constants.I2B] = I2B;
+            INSTRUCTIONS[Constants.I2C] = I2C;
+            INSTRUCTIONS[Constants.I2S] = I2S;
+            INSTRUCTIONS[Constants.LCMP] = LCMP;
+            INSTRUCTIONS[Constants.FCMPL] = FCMPL;
+            INSTRUCTIONS[Constants.FCMPG] = FCMPG;
+            INSTRUCTIONS[Constants.DCMPL] = DCMPL;
+            INSTRUCTIONS[Constants.DCMPG] = DCMPG;
+            INSTRUCTIONS[Constants.IRETURN] = IRETURN;
+            INSTRUCTIONS[Constants.LRETURN] = LRETURN;
+            INSTRUCTIONS[Constants.FRETURN] = FRETURN;
+            INSTRUCTIONS[Constants.DRETURN] = DRETURN;
+            INSTRUCTIONS[Constants.ARETURN] = ARETURN;
+            INSTRUCTIONS[Constants.RETURN] = RETURN;
+            INSTRUCTIONS[Constants.ARRAYLENGTH] = ARRAYLENGTH;
+            INSTRUCTIONS[Constants.ATHROW] = ATHROW;
+            INSTRUCTIONS[Constants.MONITORENTER] = MONITORENTER;
+            INSTRUCTIONS[Constants.MONITOREXIT] = MONITOREXIT;
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionFactory.java b/java/org/apache/tomcat/util/bcel/generic/InstructionFactory.java
new file mode 100644 (file)
index 0000000..152f8c4
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Instances of this class may be used, e.g., to generate typed
+ * versions of instructions. Its main purpose is to be used as the
+ * byte code generating backend of a compiler. You can subclass it to
+ * add your own create methods.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Constants
+ */
+public class InstructionFactory implements InstructionConstants, java.io.Serializable {
+
+       private static final String[] short_names = {
+            "C", "F", "D", "B", "S", "I", "L"
+    };
+
+    protected ClassGen cg;
+    protected ConstantPoolGen cp;
+
+
+    public InstructionFactory(ClassGen cg, ConstantPoolGen cp) {
+        this.cg = cg;
+        this.cp = cp;
+    }
+
+
+    /** Initialize with ClassGen object
+     */
+    public InstructionFactory(ClassGen cg) {
+        this(cg, cg.getConstantPool());
+    }
+
+
+    /** Initialize just with ConstantPoolGen object
+     */
+    public InstructionFactory(ConstantPoolGen cp) {
+        this(null, cp);
+    }
+
+
+    /** Create an invoke instruction.
+     *
+     * @param class_name name of the called class
+     * @param name name of the called method
+     * @param ret_type return type of method
+     * @param arg_types argument types of method
+     * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL,
+     * or INVOKESPECIAL
+     * @see Constants
+     */
+    public InvokeInstruction createInvoke( String class_name, String name, Type ret_type,
+            Type[] arg_types, short kind ) {
+        int index;
+        int nargs = 0;
+        String signature = Type.getMethodSignature(ret_type, arg_types);
+        for (int i = 0; i < arg_types.length; i++) {
+            nargs += arg_types[i].getSize();
+        }
+        if (kind == Constants.INVOKEINTERFACE) {
+            index = cp.addInterfaceMethodref(class_name, name, signature);
+        } else {
+            index = cp.addMethodref(class_name, name, signature);
+        }
+        switch (kind) {
+            case Constants.INVOKESPECIAL:
+                return new INVOKESPECIAL(index);
+            case Constants.INVOKEVIRTUAL:
+                return new INVOKEVIRTUAL(index);
+            case Constants.INVOKESTATIC:
+                return new INVOKESTATIC(index);
+            case Constants.INVOKEINTERFACE:
+                return new INVOKEINTERFACE(index, nargs + 1);
+            default:
+                throw new RuntimeException("Oops: Unknown invoke kind:" + kind);
+        }
+    }
+
+
+    /** Create a call to the most popular System.out.println() method.
+     *
+     * @param s the string to print
+     */
+    public InstructionList createPrintln( String s ) {
+        InstructionList il = new InstructionList();
+        int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
+        int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
+        il.append(new GETSTATIC(out));
+        il.append(new PUSH(cp, s));
+        il.append(new INVOKEVIRTUAL(println));
+        return il;
+    }
+
+
+    /** Uses PUSH to push a constant value onto the stack.
+     * @param value must be of type Number, Boolean, Character or String
+     */
+    public Instruction createConstant( Object value ) {
+        PUSH push;
+        if (value instanceof Number) {
+            push = new PUSH(cp, (Number) value);
+        } else if (value instanceof String) {
+            push = new PUSH(cp, (String) value);
+        } else if (value instanceof Boolean) {
+            push = new PUSH(cp, (Boolean) value);
+        } else if (value instanceof Character) {
+            push = new PUSH(cp, (Character) value);
+        } else {
+            throw new ClassGenException("Illegal type: " + value.getClass());
+        }
+        return push.getInstruction();
+    }
+
+    private static class MethodObject {
+
+        Type[] arg_types;
+        Type result_type;
+        String class_name;
+        String name;
+        int access;
+
+
+        MethodObject(String c, String n, Type r, Type[] a, int acc) {
+            class_name = c;
+            name = n;
+            result_type = r;
+            arg_types = a;
+            access = acc;
+        }
+    }
+
+
+    private InvokeInstruction createInvoke( MethodObject m, short kind ) {
+        return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind);
+    }
+
+    private static MethodObject[] append_mos = {
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.STRING
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.OBJECT
+            }, Constants.ACC_PUBLIC),
+            null,
+            null, // indices 2, 3
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.BOOLEAN
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.CHAR
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.FLOAT
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.DOUBLE
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.INT
+            }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte)
+                    new Type[] {
+                        Type.INT
+                    }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short)
+                    new Type[] {
+                        Type.INT
+                    }, Constants.ACC_PUBLIC),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.LONG
+            }, Constants.ACC_PUBLIC)
+    };
+
+
+    private static final boolean isString( Type type ) {
+        return ((type instanceof ObjectType) && ((ObjectType) type).getClassName().equals(
+                "java.lang.String"));
+    }
+
+
+    public Instruction createAppend( Type type ) {
+        byte t = type.getType();
+        if (isString(type)) {
+            return createInvoke(append_mos[0], Constants.INVOKEVIRTUAL);
+        }
+        switch (t) {
+            case Constants.T_BOOLEAN:
+            case Constants.T_CHAR:
+            case Constants.T_FLOAT:
+            case Constants.T_DOUBLE:
+            case Constants.T_BYTE:
+            case Constants.T_SHORT:
+            case Constants.T_INT:
+            case Constants.T_LONG:
+                return createInvoke(append_mos[t], Constants.INVOKEVIRTUAL);
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return createInvoke(append_mos[1], Constants.INVOKEVIRTUAL);
+            default:
+                throw new RuntimeException("Oops: No append for this type? " + type);
+        }
+    }
+
+
+    /** Create a field instruction.
+     *
+     * @param class_name name of the accessed class
+     * @param name name of the referenced field
+     * @param type  type of field
+     * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC
+     * @see Constants
+     */
+    public FieldInstruction createFieldAccess( String class_name, String name, Type type, short kind ) {
+        int index;
+        String signature = type.getSignature();
+        index = cp.addFieldref(class_name, name, signature);
+        switch (kind) {
+            case Constants.GETFIELD:
+                return new GETFIELD(index);
+            case Constants.PUTFIELD:
+                return new PUTFIELD(index);
+            case Constants.GETSTATIC:
+                return new GETSTATIC(index);
+            case Constants.PUTSTATIC:
+                return new PUTSTATIC(index);
+            default:
+                throw new RuntimeException("Oops: Unknown getfield kind:" + kind);
+        }
+    }
+
+
+    /** Create reference to `this'
+     */
+    public static Instruction createThis() {
+        return new ALOAD(0);
+    }
+
+
+    /** Create typed return
+     */
+    public static ReturnInstruction createReturn( Type type ) {
+        switch (type.getType()) {
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return ARETURN;
+            case Constants.T_INT:
+            case Constants.T_SHORT:
+            case Constants.T_BOOLEAN:
+            case Constants.T_CHAR:
+            case Constants.T_BYTE:
+                return IRETURN;
+            case Constants.T_FLOAT:
+                return FRETURN;
+            case Constants.T_DOUBLE:
+                return DRETURN;
+            case Constants.T_LONG:
+                return LRETURN;
+            case Constants.T_VOID:
+                return RETURN;
+            default:
+                throw new RuntimeException("Invalid type: " + type);
+        }
+    }
+
+
+    private static final ArithmeticInstruction createBinaryIntOp( char first, String op ) {
+        switch (first) {
+            case '-':
+                return ISUB;
+            case '+':
+                return IADD;
+            case '%':
+                return IREM;
+            case '*':
+                return IMUL;
+            case '/':
+                return IDIV;
+            case '&':
+                return IAND;
+            case '|':
+                return IOR;
+            case '^':
+                return IXOR;
+            case '<':
+                return ISHL;
+            case '>':
+                return op.equals(">>>")
+                        ? (ArithmeticInstruction) IUSHR
+                        : (ArithmeticInstruction) ISHR;
+            default:
+                throw new RuntimeException("Invalid operand " + op);
+        }
+    }
+
+
+    private static final ArithmeticInstruction createBinaryLongOp( char first, String op ) {
+        switch (first) {
+            case '-':
+                return LSUB;
+            case '+':
+                return LADD;
+            case '%':
+                return LREM;
+            case '*':
+                return LMUL;
+            case '/':
+                return LDIV;
+            case '&':
+                return LAND;
+            case '|':
+                return LOR;
+            case '^':
+                return LXOR;
+            case '<':
+                return LSHL;
+            case '>':
+                return op.equals(">>>")
+                        ? (ArithmeticInstruction) LUSHR
+                        : (ArithmeticInstruction) LSHR;
+            default:
+                throw new RuntimeException("Invalid operand " + op);
+        }
+    }
+
+
+    private static final ArithmeticInstruction createBinaryFloatOp( char op ) {
+        switch (op) {
+            case '-':
+                return FSUB;
+            case '+':
+                return FADD;
+            case '*':
+                return FMUL;
+            case '/':
+                return FDIV;
+            case '%':
+               return FREM;
+            default:
+                throw new RuntimeException("Invalid operand " + op);
+        }
+    }
+
+
+    private static final ArithmeticInstruction createBinaryDoubleOp( char op ) {
+        switch (op) {
+            case '-':
+                return DSUB;
+            case '+':
+                return DADD;
+            case '*':
+                return DMUL;
+            case '/':
+                return DDIV;
+            case '%':
+               return DREM;
+            default:
+                throw new RuntimeException("Invalid operand " + op);
+        }
+    }
+
+
+    /**
+     * Create binary operation for simple basic types, such as int and float.
+     *
+     * @param op operation, such as "+", "*", "<<", etc.
+     */
+    public static ArithmeticInstruction createBinaryOperation( String op, Type type ) {
+        char first = op.toCharArray()[0];
+        switch (type.getType()) {
+            case Constants.T_BYTE:
+            case Constants.T_SHORT:
+            case Constants.T_INT:
+            case Constants.T_CHAR:
+                return createBinaryIntOp(first, op);
+            case Constants.T_LONG:
+                return createBinaryLongOp(first, op);
+            case Constants.T_FLOAT:
+                return createBinaryFloatOp(first);
+            case Constants.T_DOUBLE:
+                return createBinaryDoubleOp(first);
+            default:
+                throw new RuntimeException("Invalid type " + type);
+        }
+    }
+
+
+    /**
+     * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+     */
+    public static StackInstruction createPop( int size ) {
+        return (size == 2) ? (StackInstruction) POP2 : (StackInstruction) POP;
+    }
+
+
+    /**
+     * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+     */
+    public static StackInstruction createDup( int size ) {
+        return (size == 2) ? (StackInstruction) DUP2 : (StackInstruction) DUP;
+    }
+
+
+    /**
+     * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+     */
+    public static StackInstruction createDup_2( int size ) {
+        return (size == 2) ? (StackInstruction) DUP2_X2 : (StackInstruction) DUP_X2;
+    }
+
+
+    /**
+     * @param size size of operand, either 1 (int, e.g.) or 2 (double)
+     */
+    public static StackInstruction createDup_1( int size ) {
+        return (size == 2) ? (StackInstruction) DUP2_X1 : (StackInstruction) DUP_X1;
+    }
+
+
+    /**
+     * @param index index of local variable
+     */
+    public static LocalVariableInstruction createStore( Type type, int index ) {
+        switch (type.getType()) {
+            case Constants.T_BOOLEAN:
+            case Constants.T_CHAR:
+            case Constants.T_BYTE:
+            case Constants.T_SHORT:
+            case Constants.T_INT:
+                return new ISTORE(index);
+            case Constants.T_FLOAT:
+                return new FSTORE(index);
+            case Constants.T_DOUBLE:
+                return new DSTORE(index);
+            case Constants.T_LONG:
+                return new LSTORE(index);
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return new ASTORE(index);
+            default:
+                throw new RuntimeException("Invalid type " + type);
+        }
+    }
+
+
+    /**
+     * @param index index of local variable
+     */
+    public static LocalVariableInstruction createLoad( Type type, int index ) {
+        switch (type.getType()) {
+            case Constants.T_BOOLEAN:
+            case Constants.T_CHAR:
+            case Constants.T_BYTE:
+            case Constants.T_SHORT:
+            case Constants.T_INT:
+                return new ILOAD(index);
+            case Constants.T_FLOAT:
+                return new FLOAD(index);
+            case Constants.T_DOUBLE:
+                return new DLOAD(index);
+            case Constants.T_LONG:
+                return new LLOAD(index);
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return new ALOAD(index);
+            default:
+                throw new RuntimeException("Invalid type " + type);
+        }
+    }
+
+
+    /**
+     * @param type type of elements of array, i.e., array.getElementType()
+     */
+    public static ArrayInstruction createArrayLoad( Type type ) {
+        switch (type.getType()) {
+            case Constants.T_BOOLEAN:
+            case Constants.T_BYTE:
+                return BALOAD;
+            case Constants.T_CHAR:
+                return CALOAD;
+            case Constants.T_SHORT:
+                return SALOAD;
+            case Constants.T_INT:
+                return IALOAD;
+            case Constants.T_FLOAT:
+                return FALOAD;
+            case Constants.T_DOUBLE:
+                return DALOAD;
+            case Constants.T_LONG:
+                return LALOAD;
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return AALOAD;
+            default:
+                throw new RuntimeException("Invalid type " + type);
+        }
+    }
+
+
+    /**
+     * @param type type of elements of array, i.e., array.getElementType()
+     */
+    public static ArrayInstruction createArrayStore( Type type ) {
+        switch (type.getType()) {
+            case Constants.T_BOOLEAN:
+            case Constants.T_BYTE:
+                return BASTORE;
+            case Constants.T_CHAR:
+                return CASTORE;
+            case Constants.T_SHORT:
+                return SASTORE;
+            case Constants.T_INT:
+                return IASTORE;
+            case Constants.T_FLOAT:
+                return FASTORE;
+            case Constants.T_DOUBLE:
+                return DASTORE;
+            case Constants.T_LONG:
+                return LASTORE;
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return AASTORE;
+            default:
+                throw new RuntimeException("Invalid type " + type);
+        }
+    }
+
+
+    /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g.,
+     * if the operands are basic types and CHECKCAST if they are reference types.
+     */
+    public Instruction createCast( Type src_type, Type dest_type ) {
+        if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) {
+            byte dest = dest_type.getType();
+            byte src = src_type.getType();
+            if (dest == Constants.T_LONG
+                    && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) {
+                src = Constants.T_INT;
+            }
+            String name = "org.apache.tomcat.util.bcel.generic." + short_names[src - Constants.T_CHAR] + "2"
+                    + short_names[dest - Constants.T_CHAR];
+            Instruction i = null;
+            try {
+                i = (Instruction) java.lang.Class.forName(name).newInstance();
+            } catch (Exception e) {
+                throw new RuntimeException("Could not find instruction: " + name, e);
+            }
+            return i;
+        } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) {
+            if (dest_type instanceof ArrayType) {
+                return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type));
+            } else {
+                return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName()));
+            }
+        } else {
+            throw new RuntimeException("Can not cast " + src_type + " to " + dest_type);
+        }
+    }
+
+
+    public GETFIELD createGetField( String class_name, String name, Type t ) {
+        return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature()));
+    }
+
+
+    public GETSTATIC createGetStatic( String class_name, String name, Type t ) {
+        return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
+    }
+
+
+    public PUTFIELD createPutField( String class_name, String name, Type t ) {
+        return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature()));
+    }
+
+
+    public PUTSTATIC createPutStatic( String class_name, String name, Type t ) {
+        return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
+    }
+
+
+    public CHECKCAST createCheckCast( ReferenceType t ) {
+        if (t instanceof ArrayType) {
+            return new CHECKCAST(cp.addArrayClass((ArrayType) t));
+        } else {
+            return new CHECKCAST(cp.addClass((ObjectType) t));
+        }
+    }
+
+
+    public INSTANCEOF createInstanceOf( ReferenceType t ) {
+        if (t instanceof ArrayType) {
+            return new INSTANCEOF(cp.addArrayClass((ArrayType) t));
+        } else {
+            return new INSTANCEOF(cp.addClass((ObjectType) t));
+        }
+    }
+
+
+    public NEW createNew( ObjectType t ) {
+        return new NEW(cp.addClass(t));
+    }
+
+
+    public NEW createNew( String s ) {
+        return createNew(new ObjectType(s));
+    }
+
+
+    /** Create new array of given size and type.
+     * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction
+     */
+    public Instruction createNewArray( Type t, short dim ) {
+        if (dim == 1) {
+            if (t instanceof ObjectType) {
+                return new ANEWARRAY(cp.addClass((ObjectType) t));
+            } else if (t instanceof ArrayType) {
+                return new ANEWARRAY(cp.addArrayClass((ArrayType) t));
+            } else {
+                return new NEWARRAY(((BasicType) t).getType());
+            }
+        } else {
+            ArrayType at;
+            if (t instanceof ArrayType) {
+                at = (ArrayType) t;
+            } else {
+                at = new ArrayType(t, dim);
+            }
+            return new MULTIANEWARRAY(cp.addArrayClass(at), dim);
+        }
+    }
+
+
+    /** Create "null" value for reference types, 0 for basic types like int
+     */
+    public static Instruction createNull( Type type ) {
+        switch (type.getType()) {
+            case Constants.T_ARRAY:
+            case Constants.T_OBJECT:
+                return ACONST_NULL;
+            case Constants.T_INT:
+            case Constants.T_SHORT:
+            case Constants.T_BOOLEAN:
+            case Constants.T_CHAR:
+            case Constants.T_BYTE:
+                return ICONST_0;
+            case Constants.T_FLOAT:
+                return FCONST_0;
+            case Constants.T_DOUBLE:
+                return DCONST_0;
+            case Constants.T_LONG:
+                return LCONST_0;
+            case Constants.T_VOID:
+                return NOP;
+            default:
+                throw new RuntimeException("Invalid type: " + type);
+        }
+    }
+
+
+    /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH.
+     * For those you should use the SWITCH compound instruction.
+     */
+    public static BranchInstruction createBranchInstruction( short opcode, InstructionHandle target ) {
+        switch (opcode) {
+            case Constants.IFEQ:
+                return new IFEQ(target);
+            case Constants.IFNE:
+                return new IFNE(target);
+            case Constants.IFLT:
+                return new IFLT(target);
+            case Constants.IFGE:
+                return new IFGE(target);
+            case Constants.IFGT:
+                return new IFGT(target);
+            case Constants.IFLE:
+                return new IFLE(target);
+            case Constants.IF_ICMPEQ:
+                return new IF_ICMPEQ(target);
+            case Constants.IF_ICMPNE:
+                return new IF_ICMPNE(target);
+            case Constants.IF_ICMPLT:
+                return new IF_ICMPLT(target);
+            case Constants.IF_ICMPGE:
+                return new IF_ICMPGE(target);
+            case Constants.IF_ICMPGT:
+                return new IF_ICMPGT(target);
+            case Constants.IF_ICMPLE:
+                return new IF_ICMPLE(target);
+            case Constants.IF_ACMPEQ:
+                return new IF_ACMPEQ(target);
+            case Constants.IF_ACMPNE:
+                return new IF_ACMPNE(target);
+            case Constants.GOTO:
+                return new GOTO(target);
+            case Constants.JSR:
+                return new JSR(target);
+            case Constants.IFNULL:
+                return new IFNULL(target);
+            case Constants.IFNONNULL:
+                return new IFNONNULL(target);
+            case Constants.GOTO_W:
+                return new GOTO_W(target);
+            case Constants.JSR_W:
+                return new JSR_W(target);
+            default:
+                throw new RuntimeException("Invalid opcode: " + opcode);
+        }
+    }
+
+
+    public void setClassGen( ClassGen c ) {
+        cg = c;
+    }
+
+
+    public ClassGen getClassGen() {
+        return cg;
+    }
+
+
+    public void setConstantPool( ConstantPoolGen c ) {
+        cp = c;
+    }
+
+
+    public ConstantPoolGen getConstantPool() {
+        return cp;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionHandle.java b/java/org/apache/tomcat/util/bcel/generic/InstructionHandle.java
new file mode 100644 (file)
index 0000000..e9423e1
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Instances of this class give users a handle to the instructions contained in
+ * an InstructionList. Instruction objects may be used more than once within a
+ * list, this is useful because it saves memory and may be much faster.
+ *
+ * Within an InstructionList an InstructionHandle object is wrapped
+ * around all instructions, i.e., it implements a cell in a
+ * doubly-linked list. From the outside only the next and the
+ * previous instruction (handle) are accessible. One
+ * can traverse the list via an Enumeration returned by
+ * InstructionList.elements().
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Instruction
+ * @see BranchHandle
+ * @see InstructionList 
+ */
+public class InstructionHandle implements java.io.Serializable {
+
+    InstructionHandle next, prev; // Will be set from the outside
+    Instruction instruction;
+    protected int i_position = -1; // byte code offset of instruction
+    private Set targeters;
+    private Map attributes;
+
+
+    public final InstructionHandle getNext() {
+        return next;
+    }
+
+
+    public final InstructionHandle getPrev() {
+        return prev;
+    }
+
+
+    public final Instruction getInstruction() {
+        return instruction;
+    }
+
+
+    /**
+     * Replace current instruction contained in this handle.
+     * Old instruction is disposed using Instruction.dispose().
+     */
+    public void setInstruction( Instruction i ) { // Overridden in BranchHandle
+        if (i == null) {
+            throw new ClassGenException("Assigning null to handle");
+        }
+        if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) {
+            throw new ClassGenException("Assigning branch instruction " + i + " to plain handle");
+        }
+        if (instruction != null) {
+            instruction.dispose();
+        }
+        instruction = i;
+    }
+
+
+    /**
+     * Temporarily swap the current instruction, without disturbing
+     * anything. Meant to be used by a debugger, implementing
+     * breakpoints. Current instruction is returned.
+     */
+    public Instruction swapInstruction( Instruction i ) {
+        Instruction oldInstruction = instruction;
+        instruction = i;
+        return oldInstruction;
+    }
+
+
+    /*private*/protected InstructionHandle(Instruction i) {
+        setInstruction(i);
+    }
+
+    private static InstructionHandle ih_list = null; // List of reusable handles
+
+
+    /** Factory method.
+     */
+    static final InstructionHandle getInstructionHandle( Instruction i ) {
+        if (ih_list == null) {
+            return new InstructionHandle(i);
+        } else {
+            InstructionHandle ih = ih_list;
+            ih_list = ih.next;
+            ih.setInstruction(i);
+            return ih;
+        }
+    }
+
+
+    /**
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions()'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
+     *
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
+     */
+    protected int updatePosition( int offset, int max_offset ) {
+        i_position += offset;
+        return 0;
+    }
+
+
+    /** @return the position, i.e., the byte code offset of the contained
+     * instruction. This is accurate only after
+     * InstructionList.setPositions() has been called.
+     */
+    public int getPosition() {
+        return i_position;
+    }
+
+
+    /** Set the position, i.e., the byte code offset of the contained
+     * instruction.
+     */
+    void setPosition( int pos ) {
+        i_position = pos;
+    }
+
+
+    /** Overridden in BranchHandle
+     */
+    protected void addHandle() {
+        next = ih_list;
+        ih_list = this;
+    }
+
+
+    /**
+     * Delete contents, i.e., remove user access and make handle reusable.
+     */
+    void dispose() {
+        next = prev = null;
+        instruction.dispose();
+        instruction = null;
+        i_position = -1;
+        attributes = null;
+        removeAllTargeters();
+        addHandle();
+    }
+
+
+    /** Remove all targeters, if any.
+     */
+    public void removeAllTargeters() {
+        if (targeters != null) {
+            targeters.clear();
+        }
+    }
+
+
+    /**
+     * Denote this handle isn't referenced anymore by t.
+     */
+    public void removeTargeter( InstructionTargeter t ) {
+        if (targeters != null) {
+            targeters.remove(t);
+        }
+    }
+
+
+    /**
+     * Denote this handle is being referenced by t.
+     */
+    public void addTargeter( InstructionTargeter t ) {
+        if (targeters == null) {
+            targeters = new HashSet();
+        }
+        //if(!targeters.contains(t))
+        targeters.add(t);
+    }
+
+
+    public boolean hasTargeters() {
+        return (targeters != null) && (targeters.size() > 0);
+    }
+
+
+    /**
+     * @return null, if there are no targeters
+     */
+    public InstructionTargeter[] getTargeters() {
+        if (!hasTargeters()) {
+            return new InstructionTargeter[0];
+        }
+        InstructionTargeter[] t = new InstructionTargeter[targeters.size()];
+        targeters.toArray(t);
+        return t;
+    }
+
+
+    /** @return a (verbose) string representation of the contained instruction. 
+     */
+    public String toString( boolean verbose ) {
+        return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose);
+    }
+
+
+    /** @return a string representation of the contained instruction. 
+     */
+    public String toString() {
+        return toString(true);
+    }
+
+
+    /** Add an attribute to an instruction handle.
+     *
+     * @param key the key object to store/retrieve the attribute
+     * @param attr the attribute to associate with this handle
+     */
+    public void addAttribute( Object key, Object attr ) {
+        if (attributes == null) {
+            attributes = new HashMap(3);
+        }
+        attributes.put(key, attr);
+    }
+
+
+    /** Delete an attribute of an instruction handle.
+     *
+     * @param key the key object to retrieve the attribute
+     */
+    public void removeAttribute( Object key ) {
+        if (attributes != null) {
+            attributes.remove(key);
+        }
+    }
+
+
+    /** Get attribute of an instruction handle.
+     *
+     * @param key the key object to store/retrieve the attribute
+     */
+    public Object getAttribute( Object key ) {
+        if (attributes != null) {
+            return attributes.get(key);
+        }
+        return null;
+    }
+
+
+    /** @return all attributes associated with this handle
+     */
+    public Collection getAttributes() {
+        if (attributes == null) {
+            attributes = new HashMap(3);
+        }
+        return attributes.values();
+    }
+
+
+    /** Convenience method, simply calls accept() on the contained instruction.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        instruction.accept(v);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionList.java b/java/org/apache/tomcat/util/bcel/generic/InstructionList.java
new file mode 100644 (file)
index 0000000..dff58d0
--- /dev/null
@@ -0,0 +1,1277 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * This class is a container for a list of <a
+ * href="Instruction.html">Instruction</a> objects. Instructions can
+ * be appended, inserted, moved, deleted, etc.. Instructions are being
+ * wrapped into <a
+ * href="InstructionHandle.html">InstructionHandles</a> objects that
+ * are returned upon append/insert operations. They give the user
+ * (read only) access to the list structure, such that it can be traversed and
+ * manipulated in a controlled way.
+ *
+ * A list is finally dumped to a byte code array with <a
+ * href="#getByteCode()">getByteCode</a>.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     Instruction
+ * @see     InstructionHandle
+ * @see BranchHandle
+ */
+public class InstructionList implements Serializable {
+
+    private InstructionHandle start = null, end = null;
+    private int length = 0; // number of elements in list
+    private int[] byte_positions; // byte code offsets corresponding to instructions
+
+
+    /**
+     * Create (empty) instruction list.
+     */
+    public InstructionList() {
+    }
+
+
+    /**
+     * Create instruction list containing one instruction.
+     * @param i initial instruction
+     */
+    public InstructionList(Instruction i) {
+        append(i);
+    }
+
+
+    /**
+     * Create instruction list containing one instruction.
+     * @param i initial instruction
+     */
+    public InstructionList(BranchInstruction i) {
+        append(i);
+    }
+
+
+    /**
+     * Initialize list with (nonnull) compound instruction. Consumes argument
+     * list, i.e., it becomes empty.
+     *
+     * @param c compound instruction (list)
+     */
+    public InstructionList(CompoundInstruction c) {
+        append(c.getInstructionList());
+    }
+
+
+    /**
+     * Test for empty list.
+     */
+    public boolean isEmpty() {
+        return start == null;
+    } // && end == null
+
+
+    /**
+     * Find the target instruction (handle) that corresponds to the given target
+     * position (byte code offset).
+     *
+     * @param ihs array of instruction handles, i.e. il.getInstructionHandles()
+     * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions()
+     * @param count length of arrays
+     * @param target target position to search for
+     * @return target position's instruction handle if available
+     */
+    public static InstructionHandle findHandle( InstructionHandle[] ihs, int[] pos, int count,
+            int target ) {
+        int l = 0, r = count - 1;
+        /* Do a binary search since the pos array is orderd.
+         */
+        do {
+            int i = (l + r) / 2;
+            int j = pos[i];
+            if (j == target) {
+                return ihs[i];
+            } else if (target < j) {
+                r = i - 1;
+            } else {
+                l = i + 1;
+            }
+        } while (l <= r);
+        return null;
+    }
+
+
+    /**
+     * Get instruction handle for instruction at byte code position pos.
+     * This only works properly, if the list is freshly initialized from a byte array or
+     * setPositions() has been called before this method.
+     *
+     * @param pos byte code position to search for
+     * @return target position's instruction handle if available
+     */
+    public InstructionHandle findHandle( int pos ) {
+       int[] positions = byte_positions;
+        InstructionHandle ih = start;
+        for (int i = 0; i < length; i++) { 
+            if(positions[i] == pos) {
+                return ih;
+            }
+            ih = ih.next;
+        }
+        return null;
+    }
+
+
+    /**
+     * Initialize instruction list from byte array.
+     *
+     * @param code byte array containing the instructions
+     */
+    public InstructionList(byte[] code) {
+        ByteSequence bytes = new ByteSequence(code);
+        InstructionHandle[] ihs = new InstructionHandle[code.length];
+        int[] pos = new int[code.length]; // Can't be more than that
+        int count = 0; // Contains actual length
+        /* Pass 1: Create an object for each byte code and append them
+         * to the list.
+         */
+        try {
+            while (bytes.available() > 0) {
+                // Remember byte offset and associate it with the instruction
+                int off = bytes.getIndex();
+                pos[count] = off;
+                /* Read one instruction from the byte stream, the byte position is set
+                 * accordingly.
+                 */
+                Instruction i = Instruction.readInstruction(bytes);
+                InstructionHandle ih;
+                if (i instanceof BranchInstruction) {
+                    ih = append((BranchInstruction) i);
+                } else {
+                    ih = append(i);
+                }
+                ih.setPosition(off);
+                ihs[count] = ih;
+                count++;
+            }
+        } catch (IOException e) {
+            throw new ClassGenException(e.toString(), e);
+        }
+        byte_positions = new int[count]; // Trim to proper size
+        System.arraycopy(pos, 0, byte_positions, 0, count);
+        /* Pass 2: Look for BranchInstruction and update their targets, i.e.,
+         * convert offsets to instruction handles.
+         */
+        for (int i = 0; i < count; i++) {
+            if (ihs[i] instanceof BranchHandle) {
+                BranchInstruction bi = (BranchInstruction) ihs[i].instruction;
+                int target = bi.position + bi.getIndex(); /* Byte code position:
+                 * relative -> absolute. */
+                // Search for target position
+                InstructionHandle ih = findHandle(ihs, pos, count, target);
+                if (ih == null) {
+                    throw new ClassGenException("Couldn't find target for branch: " + bi);
+                }
+                bi.setTarget(ih); // Update target
+                // If it is a Select instruction, update all branch targets
+                if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
+                    Select s = (Select) bi;
+                    int[] indices = s.getIndices();
+                    for (int j = 0; j < indices.length; j++) {
+                        target = bi.position + indices[j];
+                        ih = findHandle(ihs, pos, count, target);
+                        if (ih == null) {
+                            throw new ClassGenException("Couldn't find target for switch: " + bi);
+                        }
+                        s.setTarget(j, ih); // Update target      
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Append another list after instruction (handle) ih contained in this list.
+     * Consumes argument list, i.e., it becomes empty.
+     *
+     * @param ih where to append the instruction list 
+     * @param il Instruction list to append to this one
+     * @return instruction handle pointing to the <B>first</B> appended instruction
+     */
+    public InstructionHandle append( InstructionHandle ih, InstructionList il ) {
+        if (il == null) {
+            throw new ClassGenException("Appending null InstructionList");
+        }
+        if (il.isEmpty()) {
+            return ih;
+        }
+        InstructionHandle next = ih.next, ret = il.start;
+        ih.next = il.start;
+        il.start.prev = ih;
+        il.end.next = next;
+        if (next != null) {
+            next.prev = il.end;
+        } else {
+            end = il.end; // Update end ...
+        }
+        length += il.length; // Update length
+        il.clear();
+        return ret;
+    }
+
+
+    /**
+     * Append another list after instruction i contained in this list.
+     * Consumes argument list, i.e., it becomes empty.
+     *
+     * @param i  where to append the instruction list 
+     * @param il Instruction list to append to this one
+     * @return instruction handle pointing to the <B>first</B> appended instruction
+     */
+    public InstructionHandle append( Instruction i, InstructionList il ) {
+        InstructionHandle ih;
+        if ((ih = findInstruction2(i)) == null) {
+            throw new ClassGenException("Instruction " + i + " is not contained in this list.");
+        }
+        return append(ih, il);
+    }
+
+
+    /**
+     * Append another list to this one.
+     * Consumes argument list, i.e., it becomes empty.
+     *
+     * @param il list to append to end of this list
+     * @return instruction handle of the <B>first</B> appended instruction
+     */
+    public InstructionHandle append( InstructionList il ) {
+        if (il == null) {
+            throw new ClassGenException("Appending null InstructionList");
+        }
+        if (il.isEmpty()) {
+            return null;
+        }
+        if (isEmpty()) {
+            start = il.start;
+            end = il.end;
+            length = il.length;
+            il.clear();
+            return start;
+        } else {
+            return append(end, il); // was end.instruction
+        }
+    }
+
+
+    /**
+     * Append an instruction to the end of this list.
+     *
+     * @param ih instruction to append
+     */
+    private void append( InstructionHandle ih ) {
+        if (isEmpty()) {
+            start = end = ih;
+            ih.next = ih.prev = null;
+        } else {
+            end.next = ih;
+            ih.prev = end;
+            ih.next = null;
+            end = ih;
+        }
+        length++; // Update length
+    }
+
+
+    /**
+     * Append an instruction to the end of this list.
+     *
+     * @param i instruction to append
+     * @return instruction handle of the appended instruction
+     */
+    public InstructionHandle append( Instruction i ) {
+        InstructionHandle ih = InstructionHandle.getInstructionHandle(i);
+        append(ih);
+        return ih;
+    }
+
+
+    /**
+     * Append a branch instruction to the end of this list.
+     *
+     * @param i branch instruction to append
+     * @return branch instruction handle of the appended instruction
+     */
+    public BranchHandle append( BranchInstruction i ) {
+        BranchHandle ih = BranchHandle.getBranchHandle(i);
+        append(ih);
+        return ih;
+    }
+
+
+    /**
+     * Append a single instruction j after another instruction i, which
+     * must be in this list of course!
+     *
+     * @param i Instruction in list
+     * @param j Instruction to append after i in list
+     * @return instruction handle of the first appended instruction
+     */
+    public InstructionHandle append( Instruction i, Instruction j ) {
+        return append(i, new InstructionList(j));
+    }
+
+
+    /**
+     * Append a compound instruction, after instruction i.
+     *
+     * @param i Instruction in list
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first appended instruction
+     */
+    public InstructionHandle append( Instruction i, CompoundInstruction c ) {
+        return append(i, c.getInstructionList());
+    }
+
+
+    /**
+     * Append a compound instruction.
+     *
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first appended instruction
+     */
+    public InstructionHandle append( CompoundInstruction c ) {
+        return append(c.getInstructionList());
+    }
+
+
+    /**
+     * Append a compound instruction.
+     *
+     * @param ih where to append the instruction list 
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first appended instruction
+     */
+    public InstructionHandle append( InstructionHandle ih, CompoundInstruction c ) {
+        return append(ih, c.getInstructionList());
+    }
+
+
+    /**
+     * Append an instruction after instruction (handle) ih contained in this list.
+     *
+     * @param ih where to append the instruction list 
+     * @param i Instruction to append
+     * @return instruction handle pointing to the <B>first</B> appended instruction
+     */
+    public InstructionHandle append( InstructionHandle ih, Instruction i ) {
+        return append(ih, new InstructionList(i));
+    }
+
+
+    /**
+     * Append an instruction after instruction (handle) ih contained in this list.
+     *
+     * @param ih where to append the instruction list 
+     * @param i Instruction to append
+     * @return instruction handle pointing to the <B>first</B> appended instruction
+     */
+    public BranchHandle append( InstructionHandle ih, BranchInstruction i ) {
+        BranchHandle bh = BranchHandle.getBranchHandle(i);
+        InstructionList il = new InstructionList();
+        il.append(bh);
+        append(ih, il);
+        return bh;
+    }
+
+
+    /**
+     * Insert another list before Instruction handle ih contained in this list.
+     * Consumes argument list, i.e., it becomes empty.
+     *
+     * @param ih  where to append the instruction list 
+     * @param il Instruction list to insert
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( InstructionHandle ih, InstructionList il ) {
+        if (il == null) {
+            throw new ClassGenException("Inserting null InstructionList");
+        }
+        if (il.isEmpty()) {
+            return ih;
+        }
+        InstructionHandle prev = ih.prev, ret = il.start;
+        ih.prev = il.end;
+        il.end.next = ih;
+        il.start.prev = prev;
+        if (prev != null) {
+            prev.next = il.start;
+        } else {
+            start = il.start; // Update start ...
+        }
+        length += il.length; // Update length
+        il.clear();
+        return ret;
+    }
+
+
+    /**
+     * Insert another list.   
+     *
+     * @param il list to insert before start of this list
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( InstructionList il ) {
+        if (isEmpty()) {
+            append(il); // Code is identical for this case
+            return start;
+        } else {
+            return insert(start, il);
+        }
+    }
+
+
+    /**
+     * Insert an instruction at start of this list.
+     *
+     * @param ih instruction to insert
+     */
+    private void insert( InstructionHandle ih ) {
+        if (isEmpty()) {
+            start = end = ih;
+            ih.next = ih.prev = null;
+        } else {
+            start.prev = ih;
+            ih.next = start;
+            ih.prev = null;
+            start = ih;
+        }
+        length++;
+    }
+
+
+    /**
+     * Insert another list before Instruction i contained in this list.
+     * Consumes argument list, i.e., it becomes empty.
+     *
+     * @param i  where to append the instruction list 
+     * @param il Instruction list to insert
+     * @return instruction handle pointing to the first inserted instruction,
+     * i.e., il.getStart()
+     */
+    public InstructionHandle insert( Instruction i, InstructionList il ) {
+        InstructionHandle ih;
+        if ((ih = findInstruction1(i)) == null) {
+            throw new ClassGenException("Instruction " + i + " is not contained in this list.");
+        }
+        return insert(ih, il);
+    }
+
+
+    /**
+     * Insert an instruction at start of this list.
+     *
+     * @param i instruction to insert
+     * @return instruction handle of the inserted instruction
+     */
+    public InstructionHandle insert( Instruction i ) {
+        InstructionHandle ih = InstructionHandle.getInstructionHandle(i);
+        insert(ih);
+        return ih;
+    }
+
+
+    /**
+     * Insert a branch instruction at start of this list.
+     *
+     * @param i branch instruction to insert
+     * @return branch instruction handle of the appended instruction
+     */
+    public BranchHandle insert( BranchInstruction i ) {
+        BranchHandle ih = BranchHandle.getBranchHandle(i);
+        insert(ih);
+        return ih;
+    }
+
+
+    /**
+     * Insert a single instruction j before another instruction i, which
+     * must be in this list of course!
+     *
+     * @param i Instruction in list
+     * @param j Instruction to insert before i in list
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( Instruction i, Instruction j ) {
+        return insert(i, new InstructionList(j));
+    }
+
+
+    /**
+     * Insert a compound instruction before instruction i.
+     *
+     * @param i Instruction in list
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( Instruction i, CompoundInstruction c ) {
+        return insert(i, c.getInstructionList());
+    }
+
+
+    /**
+     * Insert a compound instruction.
+     *
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( CompoundInstruction c ) {
+        return insert(c.getInstructionList());
+    }
+
+
+    /**
+     * Insert an instruction before instruction (handle) ih contained in this list.
+     *
+     * @param ih where to insert to the instruction list 
+     * @param i Instruction to insert
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( InstructionHandle ih, Instruction i ) {
+        return insert(ih, new InstructionList(i));
+    }
+
+
+    /**
+     * Insert a compound instruction.
+     *
+     * @param ih where to insert the instruction list 
+     * @param c The composite instruction (containing an InstructionList)
+     * @return instruction handle of the first inserted instruction
+     */
+    public InstructionHandle insert( InstructionHandle ih, CompoundInstruction c ) {
+        return insert(ih, c.getInstructionList());
+    }
+
+
+    /**
+     * Insert an instruction before instruction (handle) ih contained in this list.
+     *
+     * @param ih where to insert to the instruction list 
+     * @param i Instruction to insert
+     * @return instruction handle of the first inserted instruction
+     */
+    public BranchHandle insert( InstructionHandle ih, BranchInstruction i ) {
+        BranchHandle bh = BranchHandle.getBranchHandle(i);
+        InstructionList il = new InstructionList();
+        il.append(bh);
+        insert(ih, il);
+        return bh;
+    }
+
+
+    /**
+     * Take all instructions (handles) from "start" to "end" and append them after the
+     * new location "target". Of course, "end" must be after "start" and target must
+     * not be located withing this range. If you want to move something to the start of
+     * the list use null as value for target.<br>
+     * Any instruction targeters pointing to handles within the block, keep their targets.
+     *
+     * @param start  of moved block
+     * @param end    of moved block
+     * @param target of moved block
+     */
+    public void move( InstructionHandle start, InstructionHandle end, InstructionHandle target ) {
+        // Step 1: Check constraints
+        if ((start == null) || (end == null)) {
+            throw new ClassGenException("Invalid null handle: From " + start + " to " + end);
+        }
+        if ((target == start) || (target == end)) {
+            throw new ClassGenException("Invalid range: From " + start + " to " + end
+                    + " contains target " + target);
+        }
+        for (InstructionHandle ih = start; ih != end.next; ih = ih.next) {
+            if (ih == null) {
+                throw new ClassGenException("Invalid range: From " + start + " to " + end);
+            } else if (ih == target) {
+                throw new ClassGenException("Invalid range: From " + start + " to " + end
+                        + " contains target " + target);
+            }
+        }
+        // Step 2: Temporarily remove the given instructions from the list
+        InstructionHandle prev = start.prev, next = end.next;
+        if (prev != null) {
+            prev.next = next;
+        } else {
+            this.start = next;
+        }
+        if (next != null) {
+            next.prev = prev;
+        } else {
+            this.end = prev;
+        }
+        start.prev = end.next = null;
+        // Step 3: append after target
+        if (target == null) { // append to start of list
+            if (this.start != null) {
+                this.start.prev = end;
+            }
+            end.next = this.start;
+            this.start = start;
+        } else {
+            next = target.next;
+            target.next = start;
+            start.prev = target;
+            end.next = next;
+            if (next != null) {
+                next.prev = end;
+            } else {
+                this.end = end;
+            }
+        }
+    }
+
+
+    /**
+     * Move a single instruction (handle) to a new location.
+     *
+     * @param ih     moved instruction
+     * @param target new location of moved instruction
+     */
+    public void move( InstructionHandle ih, InstructionHandle target ) {
+        move(ih, ih, target);
+    }
+
+
+    /**
+     * Remove from instruction `prev' to instruction `next' both contained
+     * in this list. Throws TargetLostException when one of the removed instruction handles
+     * is still being targeted.
+     *
+     * @param prev where to start deleting (predecessor, exclusive)
+     * @param next where to end deleting (successor, exclusive)
+     */
+    private void remove( InstructionHandle prev, InstructionHandle next )
+            throws TargetLostException {
+        InstructionHandle first, last; // First and last deleted instruction
+        if ((prev == null) && (next == null)) {
+            first = start;
+            last = end;
+            start = end = null;
+        } else {
+            if (prev == null) { // At start of list
+                first = start;
+                start = next;
+            } else {
+                first = prev.next;
+                prev.next = next;
+            }
+            if (next == null) { // At end of list
+                last = end;
+                end = prev;
+            } else {
+                last = next.prev;
+                next.prev = prev;
+            }
+        }
+        first.prev = null; // Completely separated from rest of list
+        last.next = null;
+        List target_vec = new ArrayList();
+        for (InstructionHandle ih = first; ih != null; ih = ih.next) {
+            ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets
+        }
+        StringBuffer buf = new StringBuffer("{ ");
+        for (InstructionHandle ih = first; ih != null; ih = next) {
+            next = ih.next;
+            length--;
+            if (ih.hasTargeters()) { // Still got targeters?
+                target_vec.add(ih);
+                buf.append(ih.toString(true) + " ");
+                ih.next = ih.prev = null;
+            } else {
+                ih.dispose();
+            }
+        }
+        buf.append("}");
+        if (!target_vec.isEmpty()) {
+            InstructionHandle[] targeted = new InstructionHandle[target_vec.size()];
+            target_vec.toArray(targeted);
+            throw new TargetLostException(targeted, buf.toString());
+        }
+    }
+
+
+    /**
+     * Remove instruction from this list. The corresponding Instruction
+     * handles must not be reused!
+     *
+     * @param ih instruction (handle) to remove 
+     */
+    public void delete( InstructionHandle ih ) throws TargetLostException {
+        remove(ih.prev, ih.next);
+    }
+
+
+    /**
+     * Remove instruction from this list. The corresponding Instruction
+     * handles must not be reused!
+     *
+     * @param i instruction to remove
+     */
+    public void delete( Instruction i ) throws TargetLostException {
+        InstructionHandle ih;
+        if ((ih = findInstruction1(i)) == null) {
+            throw new ClassGenException("Instruction " + i + " is not contained in this list.");
+        }
+        delete(ih);
+    }
+
+
+    /**
+     * Remove instructions from instruction `from' to instruction `to' contained
+     * in this list. The user must ensure that `from' is an instruction before
+     * `to', or risk havoc. The corresponding Instruction handles must not be reused!
+     *
+     * @param from where to start deleting (inclusive)
+     * @param to   where to end deleting (inclusive)
+     */
+    public void delete( InstructionHandle from, InstructionHandle to ) throws TargetLostException {
+        remove(from.prev, to.next);
+    }
+
+
+    /**
+     * Remove instructions from instruction `from' to instruction `to' contained
+     * in this list. The user must ensure that `from' is an instruction before
+     * `to', or risk havoc. The corresponding Instruction handles must not be reused!
+     *
+     * @param from where to start deleting (inclusive)
+     * @param to   where to end deleting (inclusive)
+     */
+    public void delete( Instruction from, Instruction to ) throws TargetLostException {
+        InstructionHandle from_ih, to_ih;
+        if ((from_ih = findInstruction1(from)) == null) {
+            throw new ClassGenException("Instruction " + from + " is not contained in this list.");
+        }
+        if ((to_ih = findInstruction2(to)) == null) {
+            throw new ClassGenException("Instruction " + to + " is not contained in this list.");
+        }
+        delete(from_ih, to_ih);
+    }
+
+
+    /**
+     * Search for given Instruction reference, start at beginning of list.
+     *
+     * @param i instruction to search for
+     * @return instruction found on success, null otherwise
+     */
+    private InstructionHandle findInstruction1( Instruction i ) {
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            if (ih.instruction == i) {
+                return ih;
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Search for given Instruction reference, start at end of list
+     *
+     * @param i instruction to search for
+     * @return instruction found on success, null otherwise
+     */
+    private InstructionHandle findInstruction2( Instruction i ) {
+        for (InstructionHandle ih = end; ih != null; ih = ih.prev) {
+            if (ih.instruction == i) {
+                return ih;
+            }
+        }
+        return null;
+    }
+
+
+    public boolean contains( InstructionHandle i ) {
+        if (i == null) {
+            return false;
+        }
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            if (ih == i) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public boolean contains( Instruction i ) {
+        return findInstruction1(i) != null;
+    }
+
+
+    public void setPositions() {
+        setPositions(false);
+    }
+
+
+    /**
+     * Give all instructions their position number (offset in byte stream), i.e.,
+     * make the list ready to be dumped.
+     *
+     * @param check Perform sanity checks, e.g. if all targeted instructions really belong
+     * to this list
+     */
+    public void setPositions( boolean check ) {
+        int max_additional_bytes = 0, additional_bytes = 0;
+        int index = 0, count = 0;
+        int[] pos = new int[length];
+        /* Pass 0: Sanity checks
+         */
+        if (check) {
+            for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+                Instruction i = ih.instruction;
+                if (i instanceof BranchInstruction) { // target instruction within list?
+                    Instruction inst = ((BranchInstruction) i).getTarget().instruction;
+                    if (!contains(inst)) {
+                        throw new ClassGenException("Branch target of "
+                                + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                + " not in instruction list");
+                    }
+                    if (i instanceof Select) {
+                        InstructionHandle[] targets = ((Select) i).getTargets();
+                        for (int j = 0; j < targets.length; j++) {
+                            inst = targets[j].instruction;
+                            if (!contains(inst)) {
+                                throw new ClassGenException("Branch target of "
+                                        + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                        + " not in instruction list");
+                            }
+                        }
+                    }
+                    if (!(ih instanceof BranchHandle)) {
+                        throw new ClassGenException("Branch instruction "
+                                + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                + " not contained in BranchHandle.");
+                    }
+                }
+            }
+        }
+        /* Pass 1: Set position numbers and sum up the maximum number of bytes an
+         * instruction may be shifted.
+         */
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            Instruction i = ih.instruction;
+            ih.setPosition(index);
+            pos[count++] = index;
+            /* Get an estimate about how many additional bytes may be added, because
+             * BranchInstructions may have variable length depending on the target
+             * offset (short vs. int) or alignment issues (TABLESWITCH and
+             * LOOKUPSWITCH).
+             */
+            switch (i.getOpcode()) {
+                case Constants.JSR:
+                case Constants.GOTO:
+                    max_additional_bytes += 2;
+                    break;
+                case Constants.TABLESWITCH:
+                case Constants.LOOKUPSWITCH:
+                    max_additional_bytes += 3;
+                    break;
+            }
+            index += i.getLength();
+        }
+        /* Pass 2: Expand the variable-length (Branch)Instructions depending on
+         * the target offset (short or int) and ensure that branch targets are
+         * within this list.
+         */
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes);
+        }
+        /* Pass 3: Update position numbers (which may have changed due to the
+         * preceding expansions), like pass 1.
+         */
+        index = count = 0;
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            Instruction i = ih.instruction;
+            ih.setPosition(index);
+            pos[count++] = index;
+            index += i.getLength();
+        }
+        byte_positions = new int[count]; // Trim to proper size
+        System.arraycopy(pos, 0, byte_positions, 0, count);
+    }
+
+
+    /**
+     * When everything is finished, use this method to convert the instruction
+     * list into an array of bytes.
+     *
+     * @return the byte code ready to be dumped
+     */
+    public byte[] getByteCode() {
+        // Update position indices of instructions
+        setPositions();
+        ByteArrayOutputStream b = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(b);
+        try {
+            for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+                Instruction i = ih.instruction;
+                i.dump(out); // Traverse list
+            }
+        } catch (IOException e) {
+            System.err.println(e);
+            return new byte[0];
+        }
+        return b.toByteArray();
+    }
+
+
+    /**
+     * @return an array of instructions without target information for branch instructions.
+     */
+    public Instruction[] getInstructions() {
+        ByteSequence bytes = new ByteSequence(getByteCode());
+        List instructions = new ArrayList();
+        try {
+            while (bytes.available() > 0) {
+                instructions.add(Instruction.readInstruction(bytes));
+            }
+        } catch (IOException e) {
+            throw new ClassGenException(e.toString(), e);
+        }
+        return (Instruction[]) instructions.toArray(new Instruction[instructions.size()]);
+    }
+
+
+    public String toString() {
+        return toString(true);
+    }
+
+
+    /**
+     * @param verbose toggle output format
+     * @return String containing all instructions in this list.
+     */
+    public String toString( boolean verbose ) {
+        StringBuffer buf = new StringBuffer();
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            buf.append(ih.toString(verbose)).append("\n");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return Enumeration that lists all instructions (handles)
+     */
+    public Iterator iterator() {
+        return new Iterator() {
+
+            private InstructionHandle ih = start;
+
+
+            public Object next() throws NoSuchElementException {
+               if (ih == null)
+                       throw new NoSuchElementException();
+                InstructionHandle i = ih;
+                ih = ih.next;
+                return i;
+            }
+
+
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+
+            public boolean hasNext() {
+                return ih != null;
+            }
+        };
+    }
+
+
+    /**
+     * @return array containing all instructions (handles)
+     */
+    public InstructionHandle[] getInstructionHandles() {
+        InstructionHandle[] ihs = new InstructionHandle[length];
+        InstructionHandle ih = start;
+        for (int i = 0; i < length; i++) {
+            ihs[i] = ih;
+            ih = ih.next;
+        }
+        return ihs;
+    }
+
+
+    /**
+     * Get positions (offsets) of all instructions in the list. This relies on that
+     * the list has been freshly created from an byte code array, or that setPositions()
+     * has been called. Otherwise this may be inaccurate.
+     *
+     * @return array containing all instruction's offset in byte code
+     */
+    public int[] getInstructionPositions() {
+        return byte_positions;
+    }
+
+
+    /**
+     * @return complete, i.e., deep copy of this list
+     */
+    public InstructionList copy() {
+        Map map = new HashMap();
+        InstructionList il = new InstructionList();
+        /* Pass 1: Make copies of all instructions, append them to the new list
+         * and associate old instruction references with the new ones, i.e.,
+         * a 1:1 mapping.
+         */
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            Instruction i = ih.instruction;
+            Instruction c = i.copy(); // Use clone for shallow copy
+            if (c instanceof BranchInstruction) {
+                map.put(ih, il.append((BranchInstruction) c));
+            } else {
+                map.put(ih, il.append(c));
+            }
+        }
+        /* Pass 2: Update branch targets.
+         */
+        InstructionHandle ih = start;
+        InstructionHandle ch = il.start;
+        while (ih != null) {
+            Instruction i = ih.instruction;
+            Instruction c = ch.instruction;
+            if (i instanceof BranchInstruction) {
+                BranchInstruction bi = (BranchInstruction) i;
+                BranchInstruction bc = (BranchInstruction) c;
+                InstructionHandle itarget = bi.getTarget(); // old target
+                // New target is in hash map
+                bc.setTarget((InstructionHandle) map.get(itarget));
+                if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
+                    InstructionHandle[] itargets = ((Select) bi).getTargets();
+                    InstructionHandle[] ctargets = ((Select) bc).getTargets();
+                    for (int j = 0; j < itargets.length; j++) { // Update all targets
+                        ctargets[j] = (InstructionHandle) map.get(itargets[j]);
+                    }
+                }
+            }
+            ih = ih.next;
+            ch = ch.next;
+        }
+        return il;
+    }
+
+
+    /** Replace all references to the old constant pool with references to the new
+     *  constant pool
+     */
+    public void replaceConstantPool( ConstantPoolGen old_cp, ConstantPoolGen new_cp ) {
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            Instruction i = ih.instruction;
+            if (i instanceof CPInstruction) {
+                CPInstruction ci = (CPInstruction) i;
+                Constant c = old_cp.getConstant(ci.getIndex());
+                ci.setIndex(new_cp.addConstant(c, old_cp));
+            }
+        }
+    }
+
+
+    private void clear() {
+        start = end = null;
+        length = 0;
+    }
+
+
+    /**
+     * Delete contents of list. Provides besser memory utilization,
+     * because the system then may reuse the instruction handles. This
+     * method is typically called right after
+     * <href="MethodGen.html#getMethod()">MethodGen.getMethod()</a>.
+     */
+    public void dispose() {
+        // Traverse in reverse order, because ih.next is overwritten
+        for (InstructionHandle ih = end; ih != null; ih = ih.prev) {
+            /* Causes BranchInstructions to release target and targeters, because it
+             * calls dispose() on the contained instruction.
+             */
+            ih.dispose();
+        }
+        clear();
+    }
+
+
+    /**
+     * @return start of list
+     */
+    public InstructionHandle getStart() {
+        return start;
+    }
+
+
+    /**
+     * @return end of list
+     */
+    public InstructionHandle getEnd() {
+        return end;
+    }
+
+
+    /**
+     * @return length of list (Number of instructions, not bytes)
+     */
+    public int getLength() {
+        return length;
+    }
+
+
+    /**
+     * @return length of list (Number of instructions, not bytes)
+     */
+    public int size() {
+        return length;
+    }
+
+
+    /**
+     * Redirect all references from old_target to new_target, i.e., update targets 
+     * of branch instructions.
+     *
+     * @param old_target the old target instruction handle
+     * @param new_target the new target instruction handle
+     */
+    public void redirectBranches( InstructionHandle old_target, InstructionHandle new_target ) {
+        for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+            Instruction i = ih.getInstruction();
+            if (i instanceof BranchInstruction) {
+                BranchInstruction b = (BranchInstruction) i;
+                InstructionHandle target = b.getTarget();
+                if (target == old_target) {
+                    b.setTarget(new_target);
+                }
+                if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
+                    InstructionHandle[] targets = ((Select) b).getTargets();
+                    for (int j = 0; j < targets.length; j++) {
+                        if (targets[j] == old_target) {
+                            ((Select) b).setTarget(j, new_target);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Redirect all references of local variables from old_target to new_target.
+     *
+     * @param lg array of local variables
+     * @param old_target the old target instruction handle
+     * @param new_target the new target instruction handle
+     * @see MethodGen
+     */
+    public void redirectLocalVariables( LocalVariableGen[] lg, InstructionHandle old_target,
+            InstructionHandle new_target ) {
+        for (int i = 0; i < lg.length; i++) {
+            InstructionHandle start = lg[i].getStart();
+            InstructionHandle end = lg[i].getEnd();
+            if (start == old_target) {
+                lg[i].setStart(new_target);
+            }
+            if (end == old_target) {
+                lg[i].setEnd(new_target);
+            }
+        }
+    }
+
+
+    /**
+     * Redirect all references of exception handlers from old_target to new_target.
+     *
+     * @param exceptions array of exception handlers
+     * @param old_target the old target instruction handle
+     * @param new_target the new target instruction handle
+     * @see MethodGen
+     */
+    public void redirectExceptionHandlers( CodeExceptionGen[] exceptions,
+            InstructionHandle old_target, InstructionHandle new_target ) {
+        for (int i = 0; i < exceptions.length; i++) {
+            if (exceptions[i].getStartPC() == old_target) {
+                exceptions[i].setStartPC(new_target);
+            }
+            if (exceptions[i].getEndPC() == old_target) {
+                exceptions[i].setEndPC(new_target);
+            }
+            if (exceptions[i].getHandlerPC() == old_target) {
+                exceptions[i].setHandlerPC(new_target);
+            }
+        }
+    }
+
+    private List observers;
+
+
+    /** Add observer for this object.
+     */
+    public void addObserver( InstructionListObserver o ) {
+        if (observers == null) {
+            observers = new ArrayList();
+        }
+        observers.add(o);
+    }
+
+
+    /** Remove observer for this object.
+     */
+    public void removeObserver( InstructionListObserver o ) {
+        if (observers != null) {
+            observers.remove(o);
+        }
+    }
+
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
+     */
+    public void update() {
+        if (observers != null) {
+            for (Iterator e = observers.iterator(); e.hasNext();) {
+                ((InstructionListObserver) e.next()).notify(this);
+            }
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionListObserver.java b/java/org/apache/tomcat/util/bcel/generic/InstructionListObserver.java
new file mode 100644 (file)
index 0000000..a2b1b94
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Implement this interface if you're interested in changes to an InstructionList object
+ * and register yourself with addObserver().
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface InstructionListObserver {
+
+    public void notify( InstructionList list );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InstructionTargeter.java b/java/org/apache/tomcat/util/bcel/generic/InstructionTargeter.java
new file mode 100644 (file)
index 0000000..bb29cd1
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote that a class targets InstructionHandles within an InstructionList. Namely
+ * the following implementers:
+ *
+ * @see BranchHandle
+ * @see LocalVariableGen
+ * @see CodeExceptionGen
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface InstructionTargeter {
+
+    public boolean containsTarget( InstructionHandle ih );
+
+
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/InvokeInstruction.java b/java/org/apache/tomcat/util/bcel/generic/InvokeInstruction.java
new file mode 100644 (file)
index 0000000..6e48c8f
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.StringTokenizer;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+
+/**
+ * Super class for the INVOKExxx family of instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower,
+        TypedInstruction, StackConsumer, StackProducer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    InvokeInstruction() {
+    }
+
+
+    /**
+     * @param index to constant pool
+     */
+    protected InvokeInstruction(short opcode, int index) {
+        super(opcode, index);
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        Constant c = cp.getConstant(index);
+        StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
+        return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/')
+                + tok.nextToken();
+    }
+
+
+    /**
+     * Also works for instructions whose stack effect depends on the
+     * constant pool entry they reference.
+     * @return Number of words consumed from stack by this instruction
+     */
+    public int consumeStack( ConstantPoolGen cpg ) {
+        int sum;
+        if (opcode == Constants.INVOKESTATIC) {
+            sum = 0;
+        } else {
+            sum = 1; // this reference
+        }
+        
+        String signature = getSignature(cpg);
+        sum += Type.getArgumentTypesSize(signature);
+        return sum;
+    }
+
+
+    /**
+     * Also works for instructions whose stack effect depends on the
+     * constant pool entry they reference.
+     * @return Number of words produced onto stack by this instruction
+     */
+    public int produceStack( ConstantPoolGen cpg ) {
+       String signature = getSignature(cpg);
+       return Type.getReturnTypeSize(signature);
+    }
+
+
+    /** @return return type of referenced method.
+     */
+    public Type getType( ConstantPoolGen cpg ) {
+        return getReturnType(cpg);
+    }
+
+
+    /** @return name of referenced method.
+     */
+    public String getMethodName( ConstantPoolGen cpg ) {
+        return getName(cpg);
+    }
+
+
+    /** @return return type of referenced method.
+     */
+    public Type getReturnType( ConstantPoolGen cpg ) {
+        return Type.getReturnType(getSignature(cpg));
+    }
+
+
+    /** @return argument types of referenced method.
+     */
+    public Type[] getArgumentTypes( ConstantPoolGen cpg ) {
+        return Type.getArgumentTypes(getSignature(cpg));
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/JSR.java b/java/org/apache/tomcat/util/bcel/generic/JSR.java
new file mode 100644 (file)
index 0000000..278d558
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/** 
+ * JSR - Jump to subroutine
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class JSR extends JsrInstruction implements VariableLengthInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    JSR() {
+    }
+
+
+    public JSR(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.JSR, target);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        index = getTargetOffset();
+        if (opcode == org.apache.tomcat.util.bcel.Constants.JSR) {
+            super.dump(out);
+        } else { // JSR_W
+            index = getTargetOffset();
+            out.writeByte(opcode);
+            out.writeInt(index);
+        }
+    }
+
+
+    protected int updatePosition( int offset, int max_offset ) {
+        int i = getTargetOffset(); // Depending on old position value
+        position += offset; // Position may be shifted by preceding expansions
+        if (Math.abs(i) >= (32767 - max_offset)) { // to large for short (estimate)
+            opcode = org.apache.tomcat.util.bcel.Constants.JSR_W;
+            length = 5;
+            return 2; // 5 - 3
+        }
+        return 0;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitVariableLengthInstruction(this);
+        v.visitBranchInstruction(this);
+        v.visitJsrInstruction(this);
+        v.visitJSR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/JSR_W.java b/java/org/apache/tomcat/util/bcel/generic/JSR_W.java
new file mode 100644 (file)
index 0000000..be0681f
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * JSR_W - Jump to subroutine
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class JSR_W extends JsrInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    JSR_W() {
+    }
+
+
+    public JSR_W(InstructionHandle target) {
+        super(org.apache.tomcat.util.bcel.Constants.JSR_W, target);
+        length = 5;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        index = getTargetOffset();
+        out.writeByte(opcode);
+        out.writeInt(index);
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        index = bytes.readInt();
+        length = 5;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitBranchInstruction(this);
+        v.visitJsrInstruction(this);
+        v.visitJSR_W(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/JsrInstruction.java b/java/org/apache/tomcat/util/bcel/generic/JsrInstruction.java
new file mode 100644 (file)
index 0000000..b0ebb6b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * Super class for JSR - Jump to subroutine
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch,
+        TypedInstruction, StackProducer {
+
+    JsrInstruction(short opcode, InstructionHandle target) {
+        super(opcode, target);
+    }
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    JsrInstruction() {
+    }
+
+
+    /** @return return address type
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return new ReturnaddressType(physicalSuccessor());
+    }
+
+
+    /**
+     * Returns an InstructionHandle to the physical successor
+     * of this JsrInstruction. <B>For this method to work,
+     * this JsrInstruction object must not be shared between
+     * multiple InstructionHandle objects!</B>
+     * Formally, there must not be InstructionHandle objects
+     * i, j where i != j and i.getInstruction() == this ==
+     * j.getInstruction().
+     * @return an InstructionHandle to the "next" instruction that
+     * will be executed when RETurned from a subroutine.
+     */
+    public InstructionHandle physicalSuccessor() {
+        InstructionHandle ih = this.target;
+        // Rewind!
+        while (ih.getPrev() != null) {
+            ih = ih.getPrev();
+        }
+        // Find the handle for "this" JsrInstruction object.
+        while (ih.getInstruction() != this) {
+            ih = ih.getNext();
+        }
+        InstructionHandle toThis = ih;
+        while (ih != null) {
+            ih = ih.getNext();
+            if ((ih != null) && (ih.getInstruction() == this)) {
+                throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction.");
+            }
+        }
+        // Return the physical successor               
+        return toThis.getNext();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/L2D.java b/java/org/apache/tomcat/util/bcel/generic/L2D.java
new file mode 100644 (file)
index 0000000..4fb62eb
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * L2D - Convert long to double
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class L2D extends ConversionInstruction {
+
+    public L2D() {
+        super(org.apache.tomcat.util.bcel.Constants.L2D);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitL2D(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/L2F.java b/java/org/apache/tomcat/util/bcel/generic/L2F.java
new file mode 100644 (file)
index 0000000..8c8f982
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * L2F - Convert long to float
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class L2F extends ConversionInstruction {
+
+    public L2F() {
+        super(org.apache.tomcat.util.bcel.Constants.L2F);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitL2F(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/L2I.java b/java/org/apache/tomcat/util/bcel/generic/L2I.java
new file mode 100644 (file)
index 0000000..90d256c
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * L2I - Convert long to int
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class L2I extends ConversionInstruction {
+
+    public L2I() {
+        super(org.apache.tomcat.util.bcel.Constants.L2I);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitConversionInstruction(this);
+        v.visitL2I(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LADD.java b/java/org/apache/tomcat/util/bcel/generic/LADD.java
new file mode 100644 (file)
index 0000000..a08481f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LADD - Add longs
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LADD extends ArithmeticInstruction {
+
+    public LADD() {
+        super(org.apache.tomcat.util.bcel.Constants.LADD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLADD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LALOAD.java b/java/org/apache/tomcat/util/bcel/generic/LALOAD.java
new file mode 100644 (file)
index 0000000..64f296a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LALOAD - Load long from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value1, value2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LALOAD extends ArrayInstruction implements StackProducer {
+
+    /** Load long from array
+     */
+    public LALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.LALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitLALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LAND.java b/java/org/apache/tomcat/util/bcel/generic/LAND.java
new file mode 100644 (file)
index 0000000..7ed48eb
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LAND - Bitwise AND longs
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LAND extends ArithmeticInstruction {
+
+    public LAND() {
+        super(org.apache.tomcat.util.bcel.Constants.LAND);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLAND(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LASTORE.java b/java/org/apache/tomcat/util/bcel/generic/LASTORE.java
new file mode 100644 (file)
index 0000000..32de31b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LASTORE -  Store into long array
+ * <PRE>Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LASTORE extends ArrayInstruction implements StackConsumer {
+
+    /** Store long into array
+     */
+    public LASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.LASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitLASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LCMP.java b/java/org/apache/tomcat/util/bcel/generic/LCMP.java
new file mode 100644 (file)
index 0000000..3f481e7
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * LCMP - Compare longs:
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result <= -1, 0, 1>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
+
+    public LCMP() {
+        super(org.apache.tomcat.util.bcel.Constants.LCMP, (short) 1);
+    }
+
+
+    /** @return Type.LONG
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.LONG;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitLCMP(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LCONST.java b/java/org/apache/tomcat/util/bcel/generic/LCONST.java
new file mode 100644 (file)
index 0000000..99a3138
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LCONST - Push 0 or 1, other values cause an exception
+ *
+ * <PRE>Stack: ... -&gt; ..., </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LCONST extends Instruction implements ConstantPushInstruction, TypedInstruction {
+
+    private long value;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LCONST() {
+    }
+
+
+    public LCONST(long l) {
+        super(org.apache.tomcat.util.bcel.Constants.LCONST_0, (short) 1);
+        if (l == 0) {
+            opcode = org.apache.tomcat.util.bcel.Constants.LCONST_0;
+        } else if (l == 1) {
+            opcode = org.apache.tomcat.util.bcel.Constants.LCONST_1;
+        } else {
+            throw new ClassGenException("LCONST can be used only for 0 and 1: " + l);
+        }
+        value = l;
+    }
+
+
+    public Number getValue() {
+        return new Long(value);
+    }
+
+
+    /** @return Type.LONG
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.LONG;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitLCONST(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LDC.java b/java/org/apache/tomcat/util/bcel/generic/LDC.java
new file mode 100644 (file)
index 0000000..9fae0af
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * LDC - Push item from constant pool.
+ *
+ * <PRE>Stack: ... -&gt; ..., item</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower,
+        TypedInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LDC() {
+    }
+
+
+    public LDC(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.LDC_W, index);
+        setSize();
+    }
+
+
+    // Adjust to proper size
+    protected final void setSize() {
+        if (index <= org.apache.tomcat.util.bcel.Constants.MAX_BYTE) { // Fits in one byte?
+            opcode = org.apache.tomcat.util.bcel.Constants.LDC;
+            length = 2;
+        } else {
+            opcode = org.apache.tomcat.util.bcel.Constants.LDC_W;
+            length = 3;
+        }
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        if (length == 2) {
+            out.writeByte(index);
+        } else {
+            out.writeShort(index);
+        }
+    }
+
+
+    /**
+     * Set the index to constant pool and adjust size.
+     */
+    public final void setIndex( int index ) {
+        super.setIndex(index);
+        setSize();
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        length = 2;
+        index = bytes.readUnsignedByte();
+    }
+
+
+    public Object getValue( ConstantPoolGen cpg ) {
+        org.apache.tomcat.util.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index);
+        switch (c.getTag()) {
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_String:
+                int i = ((org.apache.tomcat.util.bcel.classfile.ConstantString) c).getStringIndex();
+                c = cpg.getConstantPool().getConstant(i);
+                return ((org.apache.tomcat.util.bcel.classfile.ConstantUtf8) c).getBytes();
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Float:
+                return new Float(((org.apache.tomcat.util.bcel.classfile.ConstantFloat) c).getBytes());
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Integer:
+                return new Integer(((org.apache.tomcat.util.bcel.classfile.ConstantInteger) c).getBytes());
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Class:
+                return c;
+            default: // Never reached
+                throw new RuntimeException("Unknown or invalid constant type at " + index);
+        }
+    }
+
+
+    public Type getType( ConstantPoolGen cpg ) {
+        switch (cpg.getConstantPool().getConstant(index).getTag()) {
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_String:
+                return Type.STRING;
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Float:
+                return Type.FLOAT;
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Integer:
+                return Type.INT;
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Class:
+                return Type.CLASS;
+            default: // Never reached
+                throw new RuntimeException("Unknown or invalid constant type at " + index);
+        }
+    }
+
+
+    public Class[] getExceptions() {
+        return org.apache.tomcat.util.bcel.ExceptionConstants.EXCS_STRING_RESOLUTION;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitLDC(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LDC2_W.java b/java/org/apache/tomcat/util/bcel/generic/LDC2_W.java
new file mode 100644 (file)
index 0000000..8cb5811
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LDC2_W - Push long or double from constant pool
+ *
+ * <PRE>Stack: ... -&gt; ..., item.word1, item.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LDC2_W extends CPInstruction implements PushInstruction, TypedInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LDC2_W() {
+    }
+
+
+    public LDC2_W(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.LDC2_W, index);
+    }
+
+
+    public Type getType( ConstantPoolGen cpg ) {
+        switch (cpg.getConstantPool().getConstant(index).getTag()) {
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Long:
+                return Type.LONG;
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Double:
+                return Type.DOUBLE;
+            default: // Never reached
+                throw new RuntimeException("Unknown constant type " + opcode);
+        }
+    }
+
+
+    public Number getValue( ConstantPoolGen cpg ) {
+        org.apache.tomcat.util.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index);
+        switch (c.getTag()) {
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Long:
+                return new Long(((org.apache.tomcat.util.bcel.classfile.ConstantLong) c).getBytes());
+            case org.apache.tomcat.util.bcel.Constants.CONSTANT_Double:
+                return new Double(((org.apache.tomcat.util.bcel.classfile.ConstantDouble) c).getBytes());
+            default: // Never reached
+                throw new RuntimeException("Unknown or invalid constant type at " + index);
+        }
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitLDC2_W(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LDC_W.java b/java/org/apache/tomcat/util/bcel/generic/LDC_W.java
new file mode 100644 (file)
index 0000000..6defb63
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * LDC_W - Push item from constant pool (wide index)
+ *
+ * <PRE>Stack: ... -&gt; ..., item.word1, item.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LDC_W extends LDC {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LDC_W() {
+    }
+
+
+    public LDC_W(int index) {
+        super(index);
+    }
+
+
+    /**
+     * Read needed data (i.e., index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        setIndex(bytes.readUnsignedShort());
+        // Override just in case it has been changed
+        opcode = org.apache.tomcat.util.bcel.Constants.LDC_W;
+        length = 3;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LDIV.java b/java/org/apache/tomcat/util/bcel/generic/LDIV.java
new file mode 100644 (file)
index 0000000..628a11a
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * LDIV - Divide longs
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LDIV extends ArithmeticInstruction implements ExceptionThrower {
+
+    public LDIV() {
+        super(org.apache.tomcat.util.bcel.Constants.LDIV);
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLDIV(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LLOAD.java b/java/org/apache/tomcat/util/bcel/generic/LLOAD.java
new file mode 100644 (file)
index 0000000..f402223
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LLOAD - Load long from local variable
+ *<PRE>Stack ... -&GT; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LLOAD extends LoadInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LLOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.LLOAD, org.apache.tomcat.util.bcel.Constants.LLOAD_0);
+    }
+
+
+    public LLOAD(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.LLOAD, org.apache.tomcat.util.bcel.Constants.LLOAD_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitLLOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LMUL.java b/java/org/apache/tomcat/util/bcel/generic/LMUL.java
new file mode 100644 (file)
index 0000000..efa1b16
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LMUL - Multiply longs
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LMUL extends ArithmeticInstruction {
+
+    public LMUL() {
+        super(org.apache.tomcat.util.bcel.Constants.LMUL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLMUL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LNEG.java b/java/org/apache/tomcat/util/bcel/generic/LNEG.java
new file mode 100644 (file)
index 0000000..5b914bb
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LNEG - Negate long
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LNEG extends ArithmeticInstruction {
+
+    public LNEG() {
+        super(org.apache.tomcat.util.bcel.Constants.LNEG);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLNEG(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LOOKUPSWITCH.java b/java/org/apache/tomcat/util/bcel/generic/LOOKUPSWITCH.java
new file mode 100644 (file)
index 0000000..e278c9e
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * LOOKUPSWITCH - Switch with unordered set of values
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see SWITCH
+ */
+public class LOOKUPSWITCH extends Select {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LOOKUPSWITCH() {
+    }
+
+
+    public LOOKUPSWITCH(int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) {
+        super(org.apache.tomcat.util.bcel.Constants.LOOKUPSWITCH, match, targets, defaultTarget);
+        length = (short) (9 + match_length * 8); /* alignment remainder assumed
+         * 0 here, until dump time. */
+        fixed_length = length;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        super.dump(out);
+        out.writeInt(match_length); // npairs
+        for (int i = 0; i < match_length; i++) {
+            out.writeInt(match[i]); // match-offset pairs
+            out.writeInt(indices[i] = getTargetOffset(targets[i]));
+        }
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        super.initFromFile(bytes, wide); // reads padding
+        match_length = bytes.readInt();
+        fixed_length = (short) (9 + match_length * 8);
+        length = (short) (fixed_length + padding);
+        match = new int[match_length];
+        indices = new int[match_length];
+        targets = new InstructionHandle[match_length];
+        for (int i = 0; i < match_length; i++) {
+            match[i] = bytes.readInt();
+            indices[i] = bytes.readInt();
+        }
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitVariableLengthInstruction(this);
+        v.visitStackProducer(this);
+        v.visitBranchInstruction(this);
+        v.visitSelect(this);
+        v.visitLOOKUPSWITCH(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LOR.java b/java/org/apache/tomcat/util/bcel/generic/LOR.java
new file mode 100644 (file)
index 0000000..1e4e31f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LOR - Bitwise OR long
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LOR extends ArithmeticInstruction {
+
+    public LOR() {
+        super(org.apache.tomcat.util.bcel.Constants.LOR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLOR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LREM.java b/java/org/apache/tomcat/util/bcel/generic/LREM.java
new file mode 100644 (file)
index 0000000..20b17c5
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * LREM - Remainder of long
+ * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LREM extends ArithmeticInstruction implements ExceptionThrower {
+
+    public LREM() {
+        super(org.apache.tomcat.util.bcel.Constants.LREM);
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.ARITHMETIC_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLREM(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LRETURN.java b/java/org/apache/tomcat/util/bcel/generic/LRETURN.java
new file mode 100644 (file)
index 0000000..cd7f8a6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LRETURN -  Return long from method
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LRETURN extends ReturnInstruction {
+
+    public LRETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.LRETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitLRETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LSHL.java b/java/org/apache/tomcat/util/bcel/generic/LSHL.java
new file mode 100644 (file)
index 0000000..d12463a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LSHL - Arithmetic shift left long
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LSHL extends ArithmeticInstruction {
+
+    public LSHL() {
+        super(org.apache.tomcat.util.bcel.Constants.LSHL);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLSHL(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LSHR.java b/java/org/apache/tomcat/util/bcel/generic/LSHR.java
new file mode 100644 (file)
index 0000000..81af648
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LSHR - Arithmetic shift right long
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2 -&gt; ..., result.word1, result.word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LSHR extends ArithmeticInstruction {
+
+    public LSHR() {
+        super(org.apache.tomcat.util.bcel.Constants.LSHR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLSHR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LSTORE.java b/java/org/apache/tomcat/util/bcel/generic/LSTORE.java
new file mode 100644 (file)
index 0000000..2490af1
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LSTORE - Store long into local variable
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ... </PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LSTORE extends StoreInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    LSTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.LSTORE, org.apache.tomcat.util.bcel.Constants.LSTORE_0);
+    }
+
+
+    public LSTORE(int n) {
+        super(org.apache.tomcat.util.bcel.Constants.LSTORE, org.apache.tomcat.util.bcel.Constants.LSTORE_0, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        super.accept(v);
+        v.visitLSTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LSUB.java b/java/org/apache/tomcat/util/bcel/generic/LSUB.java
new file mode 100644 (file)
index 0000000..5961a5b
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LSUB - Substract longs
+ * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
+ *        ..., result.word1, result.word2
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LSUB extends ArithmeticInstruction {
+
+    public LSUB() {
+        super(org.apache.tomcat.util.bcel.Constants.LSUB);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLSUB(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LUSHR.java b/java/org/apache/tomcat/util/bcel/generic/LUSHR.java
new file mode 100644 (file)
index 0000000..862e498
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LUSHR - Logical shift right long
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LUSHR extends ArithmeticInstruction {
+
+    public LUSHR() {
+        super(org.apache.tomcat.util.bcel.Constants.LUSHR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLUSHR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LXOR.java b/java/org/apache/tomcat/util/bcel/generic/LXOR.java
new file mode 100644 (file)
index 0000000..93f0a99
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * LXOR - Bitwise XOR long
+ * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class LXOR extends ArithmeticInstruction {
+
+    public LXOR() {
+        super(org.apache.tomcat.util.bcel.Constants.LXOR);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitTypedInstruction(this);
+        v.visitStackProducer(this);
+        v.visitStackConsumer(this);
+        v.visitArithmeticInstruction(this);
+        v.visitLXOR(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LineNumberGen.java b/java/org/apache/tomcat/util/bcel/generic/LineNumberGen.java
new file mode 100644 (file)
index 0000000..da624e5
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.classfile.LineNumber;
+
+/** 
+ * This class represents a line number within a method, i.e., give an instruction
+ * a line number corresponding to the source code line.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     LineNumber
+ * @see     MethodGen
+ */
+public class LineNumberGen implements InstructionTargeter, Cloneable, java.io.Serializable {
+
+    private InstructionHandle ih;
+    private int src_line;
+
+
+    /**
+     * Create a line number.
+     *
+     * @param ih instruction handle to reference
+     */
+    public LineNumberGen(InstructionHandle ih, int src_line) {
+        setInstruction(ih);
+        setSourceLine(src_line);
+    }
+
+
+    /**
+     * @return true, if ih is target of this line number
+     */
+    public boolean containsTarget( InstructionHandle ih ) {
+        return this.ih == ih;
+    }
+
+
+    /**
+     * @param old_ih old target
+     * @param new_ih new target
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        if (old_ih != ih) {
+            throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}");
+        } else {
+            setInstruction(new_ih);
+        }
+    }
+
+
+    /**
+     * Get LineNumber attribute .
+     *
+     * This relies on that the instruction list has already been dumped to byte code or
+     * or that the `setPositions' methods has been called for the instruction list.
+     */
+    public LineNumber getLineNumber() {
+        return new LineNumber(ih.getPosition(), src_line);
+    }
+
+
+    public void setInstruction( InstructionHandle ih ) {
+        BranchInstruction.notifyTarget(this.ih, ih, this);
+        this.ih = ih;
+    }
+
+
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            System.err.println(e);
+            return null;
+        }
+    }
+
+
+    public InstructionHandle getInstruction() {
+        return ih;
+    }
+
+
+    public void setSourceLine( int src_line ) {
+        this.src_line = src_line;
+    }
+
+
+    public int getSourceLine() {
+        return src_line;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LoadClass.java b/java/org/apache/tomcat/util/bcel/generic/LoadClass.java
new file mode 100644 (file)
index 0000000..ffbbfe7
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes that an instruction may start the process of loading and resolving 
+ * the referenced class in the Virtual Machine.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface LoadClass {
+
+    /**
+     * Returns the ObjectType of the referenced class or interface
+     * that may be loaded and resolved.
+     * @return object type that may be loaded or null if a primitive is
+     * referenced
+     */
+    public ObjectType getLoadClassType( ConstantPoolGen cpg );
+
+
+    /**
+     * Returns the type associated with this instruction.
+     * LoadClass instances are always typed, but this type
+     * does not always refer to the type of the class or interface
+     * that it possibly forces to load. For example, GETFIELD would
+     * return the type of the field and not the type of the class
+     * where the field is defined.
+     * If no class is forced to be loaded, <B>null</B> is returned.
+     * An example for this is an ANEWARRAY instruction that creates
+     * an int[][].
+     * @see #getLoadClassType(ConstantPoolGen)
+     */
+    public Type getType( ConstantPoolGen cpg );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LoadInstruction.java b/java/org/apache/tomcat/util/bcel/generic/LoadInstruction.java
new file mode 100644 (file)
index 0000000..6a7c513
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an unparameterized instruction to load a value from a local
+ * variable, e.g. ILOAD.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     * tag and length are defined in readInstruction and initFromFile, respectively.
+     */
+    LoadInstruction(short canon_tag, short c_tag) {
+        super(canon_tag, c_tag);
+    }
+
+
+    /**
+     * @param opcode Instruction opcode
+     * @param c_tag Instruction number for compact version, ALOAD_0, e.g.
+     * @param n local variable index (unsigned short)
+     */
+    protected LoadInstruction(short opcode, short c_tag, int n) {
+        super(opcode, c_tag, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitPushInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitLocalVariableInstruction(this);
+        v.visitLoadInstruction(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LocalVariableGen.java b/java/org/apache/tomcat/util/bcel/generic/LocalVariableGen.java
new file mode 100644 (file)
index 0000000..1d7b831
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.LocalVariable;
+
+/** 
+ * This class represents a local variable within a method. It contains its
+ * scope, name and type. The generated LocalVariable object can be obtained
+ * with getLocalVariable which needs the instruction list and the constant
+ * pool as parameters.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see     LocalVariable
+ * @see     MethodGen
+ */
+public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable,
+        java.io.Serializable {
+
+    private int index;
+    private String name;
+    private Type type;
+    private InstructionHandle start, end;
+
+
+    /**
+     * Generate a local variable that with index `index'. Note that double and long
+     * variables need two indexs. Index indices have to be provided by the user.
+     *
+     * @param index index of local variable
+     * @param name its name
+     * @param type its type
+     * @param start from where the instruction is valid (null means from the start)
+     * @param end until where the instruction is valid (null means to the end)
+     */
+    public LocalVariableGen(int index, String name, Type type, InstructionHandle start,
+            InstructionHandle end) {
+        if ((index < 0) || (index > Constants.MAX_SHORT)) {
+            throw new ClassGenException("Invalid index index: " + index);
+        }
+        this.name = name;
+        this.type = type;
+        this.index = index;
+        setStart(start);
+        setEnd(end);
+    }
+
+
+    /**
+     * Get LocalVariable object.
+     *
+     * This relies on that the instruction list has already been dumped to byte code or
+     * or that the `setPositions' methods has been called for the instruction list.
+     *
+     * Note that for local variables whose scope end at the last
+     * instruction of the method's code, the JVM specification is ambiguous:
+     * both a start_pc+length ending at the last instruction and
+     * start_pc+length ending at first index beyond the end of the code are
+     * valid.
+     *
+     * @param cp constant pool
+     */
+    public LocalVariable getLocalVariable( ConstantPoolGen cp ) {
+        int start_pc = start.getPosition();
+        int length = end.getPosition() - start_pc;
+        if (length > 0) {
+            length += end.getInstruction().getLength();
+        }
+        int name_index = cp.addUtf8(name);
+        int signature_index = cp.addUtf8(type.getSignature());
+        return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
+                .getConstantPool());
+    }
+
+
+    public void setIndex( int index ) {
+        this.index = index;
+    }
+
+
+    public int getIndex() {
+        return index;
+    }
+
+
+    public void setName( String name ) {
+        this.name = name;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+
+    public void setType( Type type ) {
+        this.type = type;
+    }
+
+
+    public Type getType() {
+        return type;
+    }
+
+
+    public InstructionHandle getStart() {
+        return start;
+    }
+
+
+    public InstructionHandle getEnd() {
+        return end;
+    }
+
+
+    public void setStart( InstructionHandle start ) {
+        BranchInstruction.notifyTarget(this.start, start, this);
+        this.start = start;
+    }
+
+
+    public void setEnd( InstructionHandle end ) {
+        BranchInstruction.notifyTarget(this.end, end, this);
+        this.end = end;
+    }
+
+
+    /**
+     * @param old_ih old target, either start or end
+     * @param new_ih new target
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        boolean targeted = false;
+        if (start == old_ih) {
+            targeted = true;
+            setStart(new_ih);
+        }
+        if (end == old_ih) {
+            targeted = true;
+            setEnd(new_ih);
+        }
+        if (!targeted) {
+            throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end
+                    + "}");
+        }
+    }
+
+
+    /**
+     * @return true, if ih is target of this variable
+     */
+    public boolean containsTarget( InstructionHandle ih ) {
+        return (start == ih) || (end == ih);
+    }
+
+
+    /** @return a hash code value for the object.
+     */
+    public int hashCode() {
+        //If the user changes the name or type, problems with the targeter hashmap will occur
+        int hc = index ^ name.hashCode() ^ type.hashCode();
+        return hc;
+    }
+
+
+    /**
+     * We consider to local variables to be equal, if the use the same index and
+     * are valid in the same range.
+     */
+    public boolean equals( Object o ) {
+        if (!(o instanceof LocalVariableGen)) {
+            return false;
+        }
+        LocalVariableGen l = (LocalVariableGen) o;
+        return (l.index == index) && (l.start == start) && (l.end == end);
+    }
+
+
+    public String toString() {
+        return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
+    }
+
+
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            System.err.println(e);
+            return null;
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/LocalVariableInstruction.java b/java/org/apache/tomcat/util/bcel/generic/LocalVariableInstruction.java
new file mode 100644 (file)
index 0000000..c937337
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/**
+ * Abstract super class for instructions dealing with local variables.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction,
+        IndexedInstruction {
+
+    protected int n = -1; // index of referenced variable
+    private short c_tag = -1; // compact version, such as ILOAD_0
+    private short canon_tag = -1; // canonical tag such as ILOAD
+
+
+    private final boolean wide() {
+        return n > Constants.MAX_BYTE;
+    }
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     * tag and length are defined in readInstruction and initFromFile, respectively.
+     */
+    LocalVariableInstruction(short canon_tag, short c_tag) {
+        super();
+        this.canon_tag = canon_tag;
+        this.c_tag = c_tag;
+    }
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Also used by IINC()!
+     */
+    LocalVariableInstruction() {
+    }
+
+
+    /**
+     * @param opcode Instruction opcode
+     * @param c_tag Instruction number for compact version, ALOAD_0, e.g.
+     * @param n local variable index (unsigned short)
+     */
+    protected LocalVariableInstruction(short opcode, short c_tag, int n) {
+        super(opcode, (short) 2);
+        this.c_tag = c_tag;
+        canon_tag = opcode;
+        setIndex(n);
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        if (wide()) {
+            out.writeByte(Constants.WIDE);
+        }
+        out.writeByte(opcode);
+        if (length > 1) { // Otherwise ILOAD_n, instruction, e.g.
+            if (wide()) {
+                out.writeShort(n);
+            } else {
+                out.writeByte(n);
+            }
+        }
+    }
+
+
+    /**
+     * Long output format:
+     *
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" 
+     * "("&lt;length of instruction&gt;")" "&lt;"&lt; local variable index&gt;"&gt;"
+     *
+     * @param verbose long/short format switch
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        if (((opcode >= Constants.ILOAD_0) && (opcode <= Constants.ALOAD_3))
+                || ((opcode >= Constants.ISTORE_0) && (opcode <= Constants.ASTORE_3))) {
+            return super.toString(verbose);
+        } else {
+            return super.toString(verbose) + " " + n;
+        }
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     * PRE: (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3)
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        if (wide) {
+            n = bytes.readUnsignedShort();
+            length = 4;
+        } else if (((opcode >= Constants.ILOAD) && (opcode <= Constants.ALOAD))
+                || ((opcode >= Constants.ISTORE) && (opcode <= Constants.ASTORE))) {
+            n = bytes.readUnsignedByte();
+            length = 2;
+        } else if (opcode <= Constants.ALOAD_3) { // compact load instruction such as ILOAD_2
+            n = (opcode - Constants.ILOAD_0) % 4;
+            length = 1;
+        } else { // Assert ISTORE_0 <= tag <= ASTORE_3
+            n = (opcode - Constants.ISTORE_0) % 4;
+            length = 1;
+        }
+    }
+
+
+    /**
+     * @return local variable index  referred by this instruction.
+     */
+    public final int getIndex() {
+        return n;
+    }
+
+
+    /**
+     * Set the local variable index
+     */
+    public void setIndex( int n ) {
+        if ((n < 0) || (n > Constants.MAX_SHORT)) {
+            throw new ClassGenException("Illegal value: " + n);
+        }
+        this.n = n;
+        if (n >= 0 && n <= 3) { // Use more compact instruction xLOAD_n
+            opcode = (short) (c_tag + n);
+            length = 1;
+        } else {
+            opcode = canon_tag;
+            if (wide()) {
+                length = 4;
+            } else {
+                length = 2;
+            }
+        }
+    }
+
+
+    /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0
+     */
+    public short getCanonicalTag() {
+        return canon_tag;
+    }
+
+
+    /**
+     * Returns the type associated with the instruction - 
+     * in case of ALOAD or ASTORE Type.OBJECT is returned.
+     * This is just a bit incorrect, because ALOAD and ASTORE
+     * may work on every ReferenceType (including Type.NULL) and
+     * ASTORE may even work on a ReturnaddressType .
+     * @return type associated with the instruction
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        switch (canon_tag) {
+            case Constants.ILOAD:
+            case Constants.ISTORE:
+                return Type.INT;
+            case Constants.LLOAD:
+            case Constants.LSTORE:
+                return Type.LONG;
+            case Constants.DLOAD:
+            case Constants.DSTORE:
+                return Type.DOUBLE;
+            case Constants.FLOAD:
+            case Constants.FSTORE:
+                return Type.FLOAT;
+            case Constants.ALOAD:
+            case Constants.ASTORE:
+                return Type.OBJECT;
+            default:
+                throw new ClassGenException("Oops: unknown case in switch" + canon_tag);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/MONITORENTER.java b/java/org/apache/tomcat/util/bcel/generic/MONITORENTER.java
new file mode 100644 (file)
index 0000000..c99fd56
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * MONITORENTER - Enter monitor for object
+ * <PRE>Stack: ..., objectref -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer {
+
+    public MONITORENTER() {
+        super(org.apache.tomcat.util.bcel.Constants.MONITORENTER, (short) 1);
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackConsumer(this);
+        v.visitMONITORENTER(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/MONITOREXIT.java b/java/org/apache/tomcat/util/bcel/generic/MONITOREXIT.java
new file mode 100644 (file)
index 0000000..38d27b7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * MONITOREXIT - Exit monitor for object
+ * <PRE>Stack: ..., objectref -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer {
+
+    public MONITOREXIT() {
+        super(org.apache.tomcat.util.bcel.Constants.MONITOREXIT, (short) 1);
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackConsumer(this);
+        v.visitMONITOREXIT(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/MULTIANEWARRAY.java b/java/org/apache/tomcat/util/bcel/generic/MULTIANEWARRAY.java
new file mode 100644 (file)
index 0000000..f86b03e
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * MULTIANEWARRAY - Create new mutidimensional array of references
+ * <PRE>Stack: ..., count1, [count2, ...] -&gt; ..., arrayref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction,
+        ExceptionThrower {
+
+    private short dimensions;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    MULTIANEWARRAY() {
+    }
+
+
+    public MULTIANEWARRAY(int index, short dimensions) {
+        super(org.apache.tomcat.util.bcel.Constants.MULTIANEWARRAY, index);
+        if (dimensions < 1) {
+            throw new ClassGenException("Invalid dimensions value: " + dimensions);
+        }
+        this.dimensions = dimensions;
+        length = 4;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        out.writeShort(index);
+        out.writeByte(dimensions);
+    }
+
+
+    /**
+     * Read needed data (i.e., no. dimension) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        super.initFromFile(bytes, wide);
+        dimensions = bytes.readByte();
+        length = 4;
+    }
+
+
+    /**
+     * @return number of dimensions to be created
+     */
+    public final short getDimensions() {
+        return dimensions;
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + index + " " + dimensions;
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    public String toString( ConstantPool cp ) {
+        return super.toString(cp) + " " + dimensions;
+    }
+
+
+    /**
+     * Also works for instructions whose stack effect depends on the
+     * constant pool entry they reference.
+     * @return Number of words consumed from stack by this instruction
+     */
+    public int consumeStack( ConstantPoolGen cpg ) {
+        return dimensions;
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
+        return cs;
+    }
+
+
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        Type t = getType(cpg);
+        if (t instanceof ArrayType) {
+            t = ((ArrayType) t).getBasicType();
+        }
+        return (t instanceof ObjectType) ? (ObjectType) t : null;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLoadClass(this);
+        v.visitAllocationInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitMULTIANEWARRAY(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/MethodGen.java b/java/org/apache/tomcat/util/bcel/generic/MethodGen.java
new file mode 100644 (file)
index 0000000..17846d9
--- /dev/null
@@ -0,0 +1,1246 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.AnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.Annotations;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Code;
+import org.apache.tomcat.util.bcel.classfile.CodeException;
+import org.apache.tomcat.util.bcel.classfile.ExceptionTable;
+import org.apache.tomcat.util.bcel.classfile.LineNumber;
+import org.apache.tomcat.util.bcel.classfile.LineNumberTable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariableTable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariableTypeTable;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.ParameterAnnotationEntry;
+import org.apache.tomcat.util.bcel.classfile.ParameterAnnotations;
+import org.apache.tomcat.util.bcel.classfile.RuntimeVisibleParameterAnnotations;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+import org.apache.tomcat.util.bcel.util.BCELComparator;
+
+/** 
+ * Template class for building up a method. This is done by defining exception
+ * handlers, adding thrown exceptions, local variables and attributes, whereas
+ * the `LocalVariableTable' and `LineNumberTable' attributes will be set
+ * automatically for the code. Use stripAttributes() if you don't like this.
+ *
+ * While generating code it may be necessary to insert NOP operations. You can
+ * use the `removeNOPs' method to get rid off them.
+ * The resulting method object can be obtained via the `getMethod()' method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @author  <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
+ * @see     InstructionList
+ * @see     Method
+ */
+public class MethodGen extends FieldGenOrMethodGen {
+
+    private String class_name;
+    private Type[] arg_types;
+    private String[] arg_names;
+    private int max_locals;
+    private int max_stack;
+    private InstructionList il;
+    private boolean strip_attributes;
+    private List variable_vec = new ArrayList();
+    private List line_number_vec = new ArrayList();
+    private List exception_vec = new ArrayList();
+    private List throws_vec = new ArrayList();
+    private List code_attrs_vec = new ArrayList();
+    
+    private List[] param_annotations; // Array of lists containing AnnotationGen objects
+    private boolean hasParameterAnnotations = false;
+    private boolean haveUnpackedParameterAnnotations = false;
+    
+    private static BCELComparator _cmp = new BCELComparator() {
+
+        public boolean equals( Object o1, Object o2 ) {
+            MethodGen THIS = (MethodGen) o1;
+            MethodGen THAT = (MethodGen) o2;
+            return THIS.getName().equals(THAT.getName())
+                    && THIS.getSignature().equals(THAT.getSignature());
+        }
+
+
+        public int hashCode( Object o ) {
+            MethodGen THIS = (MethodGen) o;
+            return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+        }
+    };
+
+
+    /**
+     * Declare method. If the method is non-static the constructor
+     * automatically declares a local variable `$this' in slot 0. The
+     * actual code is contained in the `il' parameter, which may further
+     * manipulated by the user. But he must take care not to remove any
+     * instruction (handles) that are still referenced from this object.
+     *
+     * For example one may not add a local variable and later remove the
+     * instructions it refers to without causing havoc. It is safe
+     * however if you remove that local variable, too.
+     *
+     * @param access_flags access qualifiers
+     * @param return_type  method type
+     * @param arg_types argument types
+     * @param arg_names argument names (if this is null, default names will be provided
+     * for them)
+     * @param method_name name of method
+     * @param class_name class name containing this method (may be null, if you don't care)
+     * @param il instruction list associated with this method, may be null only for
+     * abstract or native methods
+     * @param cp constant pool
+     */
+    public MethodGen(int access_flags, Type return_type, Type[] arg_types, String[] arg_names,
+            String method_name, String class_name, InstructionList il, ConstantPoolGen cp) {
+        setAccessFlags(access_flags);
+        setType(return_type);
+        setArgumentTypes(arg_types);
+        setArgumentNames(arg_names);
+        setName(method_name);
+        setClassName(class_name);
+        setInstructionList(il);
+        setConstantPool(cp);
+        boolean abstract_ = isAbstract() || isNative();
+        InstructionHandle start = null;
+        InstructionHandle end = null;
+        if (!abstract_) {
+            start = il.getStart();
+            end = il.getEnd();
+            /* Add local variables, namely the implicit `this' and the arguments
+             */
+            if (!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0
+                addLocalVariable("this", new ObjectType(class_name), start, end);
+            }
+        }
+        if (arg_types != null) {
+            int size = arg_types.length;
+            for (int i = 0; i < size; i++) {
+                if (Type.VOID == arg_types[i]) {
+                    throw new ClassGenException("'void' is an illegal argument type for a method");
+                }
+            }
+            if (arg_names != null) { // Names for variables provided?
+                if (size != arg_names.length) {
+                    throw new ClassGenException("Mismatch in argument array lengths: " + size
+                            + " vs. " + arg_names.length);
+                }
+            } else { // Give them dummy names
+                arg_names = new String[size];
+                for (int i = 0; i < size; i++) {
+                    arg_names[i] = "arg" + i;
+                }
+                setArgumentNames(arg_names);
+            }
+            if (!abstract_) {
+                for (int i = 0; i < size; i++) {
+                    addLocalVariable(arg_names[i], arg_types[i], start, end);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Instantiate from existing method.
+     *
+     * @param m method
+     * @param class_name class name containing this method
+     * @param cp constant pool
+     */
+    public MethodGen(Method m, String class_name, ConstantPoolGen cp) {
+        this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m
+                .getSignature()), null /* may be overridden anyway */
+        , m.getName(), class_name,
+                ((m.getAccessFlags() & (Constants.ACC_ABSTRACT | Constants.ACC_NATIVE)) == 0)
+                        ? new InstructionList(m.getCode().getCode())
+                        : null, cp);
+        Attribute[] attributes = m.getAttributes();
+        for (int i = 0; i < attributes.length; i++) {
+            Attribute a = attributes[i];
+            if (a instanceof Code) {
+                Code c = (Code) a;
+                setMaxStack(c.getMaxStack());
+                setMaxLocals(c.getMaxLocals());
+                CodeException[] ces = c.getExceptionTable();
+                if (ces != null) {
+                    for (int j = 0; j < ces.length; j++) {
+                        CodeException ce = ces[j];
+                        int type = ce.getCatchType();
+                        ObjectType c_type = null;
+                        if (type > 0) {
+                            String cen = m.getConstantPool().getConstantString(type,
+                                    Constants.CONSTANT_Class);
+                            c_type = new ObjectType(cen);
+                        }
+                        int end_pc = ce.getEndPC();
+                        int length = m.getCode().getCode().length;
+                        InstructionHandle end;
+                        if (length == end_pc) { // May happen, because end_pc is exclusive
+                            end = il.getEnd();
+                        } else {
+                            end = il.findHandle(end_pc);
+                            end = end.getPrev(); // Make it inclusive
+                        }
+                        addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce
+                                .getHandlerPC()), c_type);
+                    }
+                }
+                Attribute[] c_attributes = c.getAttributes();
+                for (int j = 0; j < c_attributes.length; j++) {
+                    a = c_attributes[j];
+                    if (a instanceof LineNumberTable) {
+                        LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable();
+                        for (int k = 0; k < ln.length; k++) {
+                            LineNumber l = ln[k];
+                            InstructionHandle ih = il.findHandle(l.getStartPC());
+                            if (ih != null) {
+                                addLineNumber(ih, l.getLineNumber());
+                            }
+                        }
+                    } else if (a instanceof LocalVariableTable) {
+                        LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
+                        removeLocalVariables();
+                        for (int k = 0; k < lv.length; k++) {
+                            LocalVariable l = lv[k];
+                            InstructionHandle start = il.findHandle(l.getStartPC());
+                            InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
+                            // Repair malformed handles
+                            if (null == start) {
+                                start = il.getStart();
+                            }
+                            if (null == end) {
+                                end = il.getEnd();
+                            }
+                            addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
+                                    .getIndex(), start, end);
+                        }
+                    } else if (a instanceof LocalVariableTypeTable) {
+                        LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable();
+                        removeLocalVariables();
+                        for (int k = 0; k < lv.length; k++) {
+                            LocalVariable l = lv[k];
+                            InstructionHandle start = il.findHandle(l.getStartPC());
+                            InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
+                            // Repair malformed handles
+                            if (null == start) {
+                                start = il.getStart();
+                            }
+                            if (null == end) {
+                                end = il.getEnd();
+                            }
+                            addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
+                                    .getIndex(), start, end);
+                        }
+                    } else {
+                        addCodeAttribute(a);
+                    }
+                }
+            } else if (a instanceof ExceptionTable) {
+                String[] names = ((ExceptionTable) a).getExceptionNames();
+                for (int j = 0; j < names.length; j++) {
+                    addException(names[j]);
+                }
+            } else if (a instanceof Annotations) {
+                       Annotations runtimeAnnotations = (Annotations) a;
+                       AnnotationEntry[] aes = runtimeAnnotations.getAnnotationEntries();
+                       for (int k = 0; k < aes.length; k++) {
+                               AnnotationEntry element = aes[k];
+                               addAnnotationEntry(new AnnotationEntryGen(element, cp, false));
+                       }
+            } else {
+                addAttribute(a);
+            }
+        }
+    }
+
+
+    /**
+     * Adds a local variable to this method.
+     *
+     * @param name variable name
+     * @param type variable type
+     * @param slot the index of the local variable, if type is long or double, the next available
+     * index is slot+2
+     * @param start from where the variable is valid
+     * @param end until where the variable is valid
+     * @return new local variable object
+     * @see LocalVariable
+     */
+    public LocalVariableGen addLocalVariable( String name, Type type, int slot,
+            InstructionHandle start, InstructionHandle end ) {
+        byte t = type.getType();
+        if (t != Constants.T_ADDRESS) {
+            int add = type.getSize();
+            if (slot + add > max_locals) {
+                max_locals = slot + add;
+            }
+            LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
+            int i;
+            if ((i = variable_vec.indexOf(l)) >= 0) {
+                variable_vec.set(i, l);
+            } else {
+                variable_vec.add(l);
+            }
+            return l;
+        } else {
+            throw new IllegalArgumentException("Can not use " + type
+                    + " as type for local variable");
+        }
+    }
+
+
+    /**
+     * Adds a local variable to this method and assigns an index automatically.
+     *
+     * @param name variable name
+     * @param type variable type
+     * @param start from where the variable is valid, if this is null,
+     * it is valid from the start
+     * @param end until where the variable is valid, if this is null,
+     * it is valid to the end
+     * @return new local variable object
+     * @see LocalVariable
+     */
+    public LocalVariableGen addLocalVariable( String name, Type type, InstructionHandle start,
+            InstructionHandle end ) {
+        return addLocalVariable(name, type, max_locals, start, end);
+    }
+
+
+    /**
+     * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable
+     * with an explicit index argument.
+     */
+    public void removeLocalVariable( LocalVariableGen l ) {
+        variable_vec.remove(l);
+    }
+
+
+    /**
+     * Remove all local variables.
+     */
+    public void removeLocalVariables() {
+        variable_vec.clear();
+    }
+
+
+    /**
+     * Sort local variables by index
+     */
+    private static final void sort( LocalVariableGen[] vars, int l, int r ) {
+        int i = l, j = r;
+        int m = vars[(l + r) / 2].getIndex();
+        LocalVariableGen h;
+        do {
+            while (vars[i].getIndex() < m) {
+                i++;
+            }
+            while (m < vars[j].getIndex()) {
+                j--;
+            }
+            if (i <= j) {
+                h = vars[i];
+                vars[i] = vars[j];
+                vars[j] = h; // Swap elements
+                i++;
+                j--;
+            }
+        } while (i <= j);
+        if (l < j) {
+            sort(vars, l, j);
+        }
+        if (i < r) {
+            sort(vars, i, r);
+        }
+    }
+
+
+    /*
+     * If the range of the variable has not been set yet, it will be set to be valid from
+     * the start to the end of the instruction list.
+     * 
+     * @return array of declared local variables sorted by index
+     */
+    public LocalVariableGen[] getLocalVariables() {
+        int size = variable_vec.size();
+        LocalVariableGen[] lg = new LocalVariableGen[size];
+        variable_vec.toArray(lg);
+        for (int i = 0; i < size; i++) {
+            if (lg[i].getStart() == null) {
+                lg[i].setStart(il.getStart());
+            }
+            if (lg[i].getEnd() == null) {
+                lg[i].setEnd(il.getEnd());
+            }
+        }
+        if (size > 1) {
+            sort(lg, 0, size - 1);
+        }
+        return lg;
+    }
+
+
+    /**
+     * @return `LocalVariableTable' attribute of all the local variables of this method.
+     */
+    public LocalVariableTable getLocalVariableTable( ConstantPoolGen cp ) {
+        LocalVariableGen[] lg = getLocalVariables();
+        int size = lg.length;
+        LocalVariable[] lv = new LocalVariable[size];
+        for (int i = 0; i < size; i++) {
+            lv[i] = lg[i].getLocalVariable(cp);
+        }
+        return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp
+                .getConstantPool());
+    }
+
+
+    /**
+     * Give an instruction a line number corresponding to the source code line.
+     *
+     * @param ih instruction to tag
+     * @return new line number object
+     * @see LineNumber
+     */
+    public LineNumberGen addLineNumber( InstructionHandle ih, int src_line ) {
+        LineNumberGen l = new LineNumberGen(ih, src_line);
+        line_number_vec.add(l);
+        return l;
+    }
+
+
+    /**
+     * Remove a line number.
+     */
+    public void removeLineNumber( LineNumberGen l ) {
+        line_number_vec.remove(l);
+    }
+
+
+    /**
+     * Remove all line numbers.
+     */
+    public void removeLineNumbers() {
+        line_number_vec.clear();
+    }
+
+
+    /*
+     * @return array of line numbers
+     */
+    public LineNumberGen[] getLineNumbers() {
+        LineNumberGen[] lg = new LineNumberGen[line_number_vec.size()];
+        line_number_vec.toArray(lg);
+        return lg;
+    }
+
+
+    /**
+     * @return `LineNumberTable' attribute of all the local variables of this method.
+     */
+    public LineNumberTable getLineNumberTable( ConstantPoolGen cp ) {
+        int size = line_number_vec.size();
+        LineNumber[] ln = new LineNumber[size];
+        try {
+            for (int i = 0; i < size; i++) {
+                ln[i] = ((LineNumberGen) line_number_vec.get(i)).getLineNumber();
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+        } // Never occurs
+        return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp
+                .getConstantPool());
+    }
+
+
+    /**
+     * Add an exception handler, i.e., specify region where a handler is active and an
+     * instruction where the actual handling is done.
+     *
+     * @param start_pc Start of region (inclusive)
+     * @param end_pc End of region (inclusive)
+     * @param handler_pc Where handling is done
+     * @param catch_type class type of handled exception or null if any
+     * exception is handled
+     * @return new exception handler object
+     */
+    public CodeExceptionGen addExceptionHandler( InstructionHandle start_pc,
+            InstructionHandle end_pc, InstructionHandle handler_pc, ObjectType catch_type ) {
+        if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) {
+            throw new ClassGenException("Exception handler target is null instruction");
+        }
+        CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type);
+        exception_vec.add(c);
+        return c;
+    }
+
+
+    /**
+     * Remove an exception handler.
+     */
+    public void removeExceptionHandler( CodeExceptionGen c ) {
+        exception_vec.remove(c);
+    }
+
+
+    /**
+     * Remove all line numbers.
+     */
+    public void removeExceptionHandlers() {
+        exception_vec.clear();
+    }
+
+
+    /*
+     * @return array of declared exception handlers
+     */
+    public CodeExceptionGen[] getExceptionHandlers() {
+        CodeExceptionGen[] cg = new CodeExceptionGen[exception_vec.size()];
+        exception_vec.toArray(cg);
+        return cg;
+    }
+
+
+    /**
+     * @return code exceptions for `Code' attribute
+     */
+    private CodeException[] getCodeExceptions() {
+        int size = exception_vec.size();
+        CodeException[] c_exc = new CodeException[size];
+        try {
+            for (int i = 0; i < size; i++) {
+                CodeExceptionGen c = (CodeExceptionGen) exception_vec.get(i);
+                c_exc[i] = c.getCodeException(cp);
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        return c_exc;
+    }
+
+
+    /**
+     * Add an exception possibly thrown by this method.
+     *
+     * @param class_name (fully qualified) name of exception
+     */
+    public void addException( String class_name ) {
+        throws_vec.add(class_name);
+    }
+
+
+    /**
+     * Remove an exception.
+     */
+    public void removeException( String c ) {
+        throws_vec.remove(c);
+    }
+
+
+    /**
+     * Remove all exceptions.
+     */
+    public void removeExceptions() {
+        throws_vec.clear();
+    }
+
+
+    /*
+     * @return array of thrown exceptions
+     */
+    public String[] getExceptions() {
+        String[] e = new String[throws_vec.size()];
+        throws_vec.toArray(e);
+        return e;
+    }
+
+
+    /**
+     * @return `Exceptions' attribute of all the exceptions thrown by this method.
+     */
+    private ExceptionTable getExceptionTable( ConstantPoolGen cp ) {
+        int size = throws_vec.size();
+        int[] ex = new int[size];
+        try {
+            for (int i = 0; i < size; i++) {
+                ex[i] = cp.addClass((String) throws_vec.get(i));
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool());
+    }
+
+
+    /**
+     * Add an attribute to the code. Currently, the JVM knows about the
+     * LineNumberTable, LocalVariableTable and StackMap attributes,
+     * where the former two will be generated automatically and the
+     * latter is used for the MIDP only. Other attributes will be
+     * ignored by the JVM but do no harm.
+     *
+     * @param a attribute to be added
+     */
+    public void addCodeAttribute( Attribute a ) {
+        code_attrs_vec.add(a);
+    }
+
+
+    /**
+     * Remove a code attribute.
+     */
+    public void removeCodeAttribute( Attribute a ) {
+        code_attrs_vec.remove(a);
+    }
+
+
+    /**
+     * Remove all code attributes.
+     */
+    public void removeCodeAttributes() {
+        code_attrs_vec.clear();
+    }
+
+
+    /**
+     * @return all attributes of this method.
+     */
+    public Attribute[] getCodeAttributes() {
+        Attribute[] attributes = new Attribute[code_attrs_vec.size()];
+        code_attrs_vec.toArray(attributes);
+        return attributes;
+    }
+    
+    public void addAnnotationsAsAttribute(ConstantPoolGen cp) {
+       Attribute[] attrs = Utility.getAnnotationAttributes(cp,annotation_vec);
+        for (int i = 0; i < attrs.length; i++) {
+               addAttribute(attrs[i]);
+       }
+      }
+      
+      public void addParameterAnnotationsAsAttribute(ConstantPoolGen cp) {
+       if (!hasParameterAnnotations) return;
+       Attribute[] attrs = Utility.getParameterAnnotationAttributes(cp,param_annotations);
+       if (attrs!=null) {
+          for (int i = 0; i < attrs.length; i++) {
+                 addAttribute(attrs[i]);
+         }
+       }
+      }
+
+
+    /**
+     * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively,
+     * before calling this method (the same applies for max locals).
+     *
+     * @return method object
+     */
+    public Method getMethod() {
+        String signature = getSignature();
+        int name_index = cp.addUtf8(name);
+        int signature_index = cp.addUtf8(signature);
+        /* Also updates positions of instructions, i.e., their indices
+         */
+        byte[] byte_code = null;
+        if (il != null) {
+            byte_code = il.getByteCode();
+        }
+        LineNumberTable lnt = null;
+        LocalVariableTable lvt = null;
+        /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
+         */
+        if ((variable_vec.size() > 0) && !strip_attributes) {
+            addCodeAttribute(lvt = getLocalVariableTable(cp));
+        }
+        if ((line_number_vec.size() > 0) && !strip_attributes) {
+            addCodeAttribute(lnt = getLineNumberTable(cp));
+        }
+        Attribute[] code_attrs = getCodeAttributes();
+        /* Each attribute causes 6 additional header bytes
+         */
+        int attrs_len = 0;
+        for (int i = 0; i < code_attrs.length; i++) {
+            attrs_len += (code_attrs[i].getLength() + 6);
+        }
+        CodeException[] c_exc = getCodeExceptions();
+        int exc_len = c_exc.length * 8; // Every entry takes 8 bytes
+        Code code = null;
+        if ((il != null) && !isAbstract() && !isNative()) {
+            // Remove any stale code attribute
+            Attribute[] attributes = getAttributes();
+            for (int i = 0; i < attributes.length; i++) {
+                Attribute a = attributes[i];
+                if (a instanceof Code) {
+                    removeAttribute(a);
+                }
+            }
+            code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code
+                    2 + exc_len + // exceptions
+                    2 + attrs_len, // attributes
+                    max_stack, max_locals, byte_code, c_exc, code_attrs, cp.getConstantPool());
+            addAttribute(code);
+        }
+        addAnnotationsAsAttribute(cp);
+        addParameterAnnotationsAsAttribute(cp);
+        ExceptionTable et = null;
+        if (throws_vec.size() > 0) {
+            addAttribute(et = getExceptionTable(cp));
+            // Add `Exceptions' if there are "throws" clauses
+        }
+        Method m = new Method(access_flags, name_index, signature_index, getAttributes(), cp
+                .getConstantPool());
+        // Undo effects of adding attributes
+        if (lvt != null) {
+            removeCodeAttribute(lvt);
+        }
+        if (lnt != null) {
+            removeCodeAttribute(lnt);
+        }
+        if (code != null) {
+            removeAttribute(code);
+        }
+        if (et != null) {
+            removeAttribute(et);
+        }
+        return m;
+    }
+
+
+    /**
+     * Remove all NOPs from the instruction list (if possible) and update every
+     * object refering to them, i.e., branch instructions, local variables and
+     * exception handlers.
+     */
+    public void removeNOPs() {
+        if (il != null) {
+            InstructionHandle next;
+            /* Check branch instructions.
+             */
+            for (InstructionHandle ih = il.getStart(); ih != null; ih = next) {
+                next = ih.next;
+                if ((next != null) && (ih.getInstruction() instanceof NOP)) {
+                    try {
+                        il.delete(ih);
+                    } catch (TargetLostException e) {
+                        InstructionHandle[] targets = e.getTargets();
+                        for (int i = 0; i < targets.length; i++) {
+                            InstructionTargeter[] targeters = targets[i].getTargeters();
+                            for (int j = 0; j < targeters.length; j++) {
+                                targeters[j].updateTarget(targets[i], next);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Set maximum number of local variables.
+     */
+    public void setMaxLocals( int m ) {
+        max_locals = m;
+    }
+
+
+    public int getMaxLocals() {
+        return max_locals;
+    }
+
+
+    /**
+     * Set maximum stack size for this method.
+     */
+    public void setMaxStack( int m ) {
+        max_stack = m;
+    }
+
+
+    public int getMaxStack() {
+        return max_stack;
+    }
+
+
+    /** @return class that contains this method
+     */
+    public String getClassName() {
+        return class_name;
+    }
+
+
+    public void setClassName( String class_name ) {
+        this.class_name = class_name;
+    }
+
+
+    public void setReturnType( Type return_type ) {
+        setType(return_type);
+    }
+
+
+    public Type getReturnType() {
+        return getType();
+    }
+
+
+    public void setArgumentTypes( Type[] arg_types ) {
+        this.arg_types = arg_types;
+    }
+
+
+    public Type[] getArgumentTypes() {
+        return (Type[]) arg_types.clone();
+    }
+
+
+    public void setArgumentType( int i, Type type ) {
+        arg_types[i] = type;
+    }
+
+
+    public Type getArgumentType( int i ) {
+        return arg_types[i];
+    }
+
+
+    public void setArgumentNames( String[] arg_names ) {
+        this.arg_names = arg_names;
+    }
+
+
+    public String[] getArgumentNames() {
+        return (String[]) arg_names.clone();
+    }
+
+
+    public void setArgumentName( int i, String name ) {
+        arg_names[i] = name;
+    }
+
+
+    public String getArgumentName( int i ) {
+        return arg_names[i];
+    }
+
+
+    public InstructionList getInstructionList() {
+        return il;
+    }
+
+
+    public void setInstructionList( InstructionList il ) {
+        this.il = il;
+    }
+
+
+    public String getSignature() {
+        return Type.getMethodSignature(type, arg_types);
+    }
+
+
+    /**
+     * Computes max. stack size by performing control flow analysis.
+     */
+    public void setMaxStack() {
+        if (il != null) {
+            max_stack = getMaxStack(cp, il, getExceptionHandlers());
+        } else {
+            max_stack = 0;
+        }
+    }
+
+
+    /**
+     * Compute maximum number of local variables.
+     */
+    public void setMaxLocals() {
+        if (il != null) {
+            int max = isStatic() ? 0 : 1;
+            if (arg_types != null) {
+                for (int i = 0; i < arg_types.length; i++) {
+                    max += arg_types[i].getSize();
+                }
+            }
+            for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
+                Instruction ins = ih.getInstruction();
+                if ((ins instanceof LocalVariableInstruction) || (ins instanceof RET)
+                        || (ins instanceof IINC)) {
+                    int index = ((IndexedInstruction) ins).getIndex()
+                            + ((TypedInstruction) ins).getType(cp).getSize();
+                    if (index > max) {
+                        max = index;
+                    }
+                }
+            }
+            max_locals = max;
+        } else {
+            max_locals = 0;
+        }
+    }
+
+
+    /** Do not/Do produce attributes code attributesLineNumberTable and
+     * LocalVariableTable, like javac -O
+     */
+    public void stripAttributes( boolean flag ) {
+        strip_attributes = flag;
+    }
+
+    static final class BranchTarget {
+
+        InstructionHandle target;
+        int stackDepth;
+
+
+        BranchTarget(InstructionHandle target, int stackDepth) {
+            this.target = target;
+            this.stackDepth = stackDepth;
+        }
+    }
+
+    static final class BranchStack {
+
+        Stack branchTargets = new Stack();
+        Hashtable visitedTargets = new Hashtable();
+
+
+        public void push( InstructionHandle target, int stackDepth ) {
+            if (visited(target)) {
+                return;
+            }
+            branchTargets.push(visit(target, stackDepth));
+        }
+
+
+        public BranchTarget pop() {
+            if (!branchTargets.empty()) {
+                BranchTarget bt = (BranchTarget) branchTargets.pop();
+                return bt;
+            }
+            return null;
+        }
+
+
+        private final BranchTarget visit( InstructionHandle target, int stackDepth ) {
+            BranchTarget bt = new BranchTarget(target, stackDepth);
+            visitedTargets.put(target, bt);
+            return bt;
+        }
+
+
+        private final boolean visited( InstructionHandle target ) {
+            return (visitedTargets.get(target) != null);
+        }
+    }
+
+
+    /**
+     * Computes stack usage of an instruction list by performing control flow analysis.
+     *
+     * @return maximum stack depth used by method
+     */
+    public static int getMaxStack( ConstantPoolGen cp, InstructionList il, CodeExceptionGen[] et ) {
+        BranchStack branchTargets = new BranchStack();
+        /* Initially, populate the branch stack with the exception
+         * handlers, because these aren't (necessarily) branched to
+         * explicitly. in each case, the stack will have depth 1,
+         * containing the exception object.
+         */
+        for (int i = 0; i < et.length; i++) {
+            InstructionHandle handler_pc = et[i].getHandlerPC();
+            if (handler_pc != null) {
+                branchTargets.push(handler_pc, 1);
+            }
+        }
+        int stackDepth = 0, maxStackDepth = 0;
+        InstructionHandle ih = il.getStart();
+        while (ih != null) {
+            Instruction instruction = ih.getInstruction();
+            short opcode = instruction.getOpcode();
+            int delta = instruction.produceStack(cp) - instruction.consumeStack(cp);
+            stackDepth += delta;
+            if (stackDepth > maxStackDepth) {
+                maxStackDepth = stackDepth;
+            }
+            // choose the next instruction based on whether current is a branch.
+            if (instruction instanceof BranchInstruction) {
+                BranchInstruction branch = (BranchInstruction) instruction;
+                if (instruction instanceof Select) {
+                    // explore all of the select's targets. the default target is handled below.
+                    Select select = (Select) branch;
+                    InstructionHandle[] targets = select.getTargets();
+                    for (int i = 0; i < targets.length; i++) {
+                        branchTargets.push(targets[i], stackDepth);
+                    }
+                    // nothing to fall through to.
+                    ih = null;
+                } else if (!(branch instanceof IfInstruction)) {
+                    // if an instruction that comes back to following PC,
+                    // push next instruction, with stack depth reduced by 1.
+                    if (opcode == Constants.JSR || opcode == Constants.JSR_W) {
+                        branchTargets.push(ih.getNext(), stackDepth - 1);
+                    }
+                    ih = null;
+                }
+                // for all branches, the target of the branch is pushed on the branch stack.
+                // conditional branches have a fall through case, selects don't, and
+                // jsr/jsr_w return to the next instruction.
+                branchTargets.push(branch.getTarget(), stackDepth);
+            } else {
+                // check for instructions that terminate the method.
+                if (opcode == Constants.ATHROW || opcode == Constants.RET
+                        || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) {
+                    ih = null;
+                }
+            }
+            // normal case, go to the next instruction.
+            if (ih != null) {
+                ih = ih.getNext();
+            }
+            // if we have no more instructions, see if there are any deferred branches to explore.
+            if (ih == null) {
+                BranchTarget bt = branchTargets.pop();
+                if (bt != null) {
+                    ih = bt.target;
+                    stackDepth = bt.stackDepth;
+                }
+            }
+        }
+        return maxStackDepth;
+    }
+
+    private List observers;
+
+
+    /** Add observer for this object.
+     */
+    public void addObserver( MethodObserver o ) {
+        if (observers == null) {
+            observers = new ArrayList();
+        }
+        observers.add(o);
+    }
+
+
+    /** Remove observer for this object.
+     */
+    public void removeObserver( MethodObserver o ) {
+        if (observers != null) {
+            observers.remove(o);
+        }
+    }
+
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
+     */
+    public void update() {
+        if (observers != null) {
+            for (Iterator e = observers.iterator(); e.hasNext();) {
+                ((MethodObserver) e.next()).notify(this);
+            }
+        }
+    }
+
+
+    /**
+     * Return string representation close to declaration format,
+     * `public static void main(String[]) throws IOException', e.g.
+     *
+     * @return String representation of the method.
+     */
+    public final String toString() {
+        String access = Utility.accessToString(access_flags);
+        String signature = Type.getMethodSignature(type, arg_types);
+        signature = Utility.methodSignatureToString(signature, name, access, true,
+                getLocalVariableTable(cp));
+        StringBuffer buf = new StringBuffer(signature);
+        for (int i = 0; i < getAttributes().length; i++) {
+            Attribute a = getAttributes()[i];
+            if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
+                buf.append(" [").append(a.toString()).append("]");
+            }
+        }
+        
+        if (throws_vec.size() > 0) {
+            for (Iterator e = throws_vec.iterator(); e.hasNext();) {
+                buf.append("\n\t\tthrows ").append(e.next());
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /** @return deep copy of this method
+     */
+    public MethodGen copy( String class_name, ConstantPoolGen cp ) {
+        Method m = ((MethodGen) clone()).getMethod();
+        MethodGen mg = new MethodGen(m, class_name, this.cp);
+        if (this.cp != cp) {
+            mg.setConstantPool(cp);
+            mg.getInstructionList().replaceConstantPool(this.cp, cp);
+        }
+        return mg;
+    }
+    
+    //J5TODO: Should param_annotations be an array of arrays? Rather than an array of lists, this
+    // is more likely to suggest to the caller it is readonly (which a List does not). 
+    /**
+     * Return a list of AnnotationGen objects representing parameter annotations
+     */
+    public List getAnnotationsOnParameter(int i) {
+       ensureExistingParameterAnnotationsUnpacked();
+       if (!hasParameterAnnotations || i>arg_types.length) return null;
+       return param_annotations[i];
+    }
+    
+    /**
+        * Goes through the attributes on the method and identifies any that are
+        * RuntimeParameterAnnotations, extracting their contents and storing them
+        * as parameter annotations. There are two kinds of parameter annotation -
+        * visible and invisible. Once they have been unpacked, these attributes are
+        * deleted. (The annotations will be rebuilt as attributes when someone
+        * builds a Method object out of this MethodGen object).
+        */
+       private void ensureExistingParameterAnnotationsUnpacked()
+       {
+               if (haveUnpackedParameterAnnotations)
+                       return;
+               // Find attributes that contain parameter annotation data
+               Attribute[] attrs = getAttributes();
+               ParameterAnnotations paramAnnVisAttr = null;
+               ParameterAnnotations paramAnnInvisAttr = null;
+               for (int i = 0; i < attrs.length; i++)
+               {
+                       Attribute attribute = attrs[i];
+                       if (attribute instanceof ParameterAnnotations)
+                       {
+                               // Initialize param_annotations
+                               if (!hasParameterAnnotations)
+                               {
+                                       param_annotations = new List[arg_types.length];
+                                       for (int j = 0; j < arg_types.length; j++)
+                                               param_annotations[j] = new ArrayList();
+                               }
+                               hasParameterAnnotations = true;
+                               ParameterAnnotations rpa = (ParameterAnnotations) attribute;
+                               if (rpa instanceof RuntimeVisibleParameterAnnotations)
+                                       paramAnnVisAttr = rpa;
+                               else
+                                       paramAnnInvisAttr = rpa;
+                               for (int j = 0; j < arg_types.length; j++)
+                               {
+                                       // This returns Annotation[] ...
+                                       ParameterAnnotationEntry immutableArray = rpa
+                                                       .getParameterAnnotationEntries()[j];
+                                       // ... which needs transforming into an AnnotationGen[] ...
+                                       List mutable = makeMutableVersion(immutableArray.getAnnotationEntries());
+                                       // ... then add these to any we already know about
+                                       param_annotations[j].addAll(mutable);
+                               }
+                       }
+               }
+               if (paramAnnVisAttr != null)
+                       removeAttribute(paramAnnVisAttr);
+               if (paramAnnInvisAttr != null)
+                       removeAttribute(paramAnnInvisAttr);
+               haveUnpackedParameterAnnotations = true;
+       }
+
+       private List /* AnnotationGen */makeMutableVersion(AnnotationEntry[] mutableArray)
+       {
+               List result = new ArrayList();
+               for (int i = 0; i < mutableArray.length; i++)
+               {
+                       result.add(new AnnotationEntryGen(mutableArray[i], getConstantPool(),
+                                       false));
+               }
+               return result;
+       }
+
+       public void addParameterAnnotation(int parameterIndex,
+                       AnnotationEntryGen annotation)
+       {
+               ensureExistingParameterAnnotationsUnpacked();
+               if (!hasParameterAnnotations)
+               {
+                       param_annotations = new List[arg_types.length];
+                       hasParameterAnnotations = true;
+               }
+               List existingAnnotations = param_annotations[parameterIndex];
+               if (existingAnnotations != null)
+               {
+                       existingAnnotations.add(annotation);
+               }
+               else
+               {
+                       List l = new ArrayList();
+                       l.add(annotation);
+                       param_annotations[parameterIndex] = l;
+               }
+       }          
+
+
+
+
+    /**
+        * @return Comparison strategy object
+        */
+    public static BCELComparator getComparator() {
+        return _cmp;
+    }
+
+
+    /**
+     * @param comparator Comparison strategy object
+     */
+    public static void setComparator( BCELComparator comparator ) {
+        _cmp = comparator;
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default two MethodGen objects are said to be equal when
+     * their names and signatures are equal.
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals( Object obj ) {
+        return _cmp.equals(this, obj);
+    }
+
+
+    /**
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the method's name XOR signature.
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return _cmp.hashCode(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/MethodObserver.java b/java/org/apache/tomcat/util/bcel/generic/MethodObserver.java
new file mode 100644 (file)
index 0000000..15618f3
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Implement this interface if you're interested in changes to a MethodGen object
+ * and register yourself with addObserver().
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface MethodObserver {
+
+    public void notify( MethodGen method );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/NEW.java b/java/org/apache/tomcat/util/bcel/generic/NEW.java
new file mode 100644 (file)
index 0000000..9d2aeb5
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * NEW - Create new object
+ * <PRE>Stack: ... -&gt; ..., objectref</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class NEW extends CPInstruction implements LoadClass, AllocationInstruction,
+        ExceptionThrower, StackProducer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    NEW() {
+    }
+
+
+    public NEW(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.NEW, index);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.INSTANTIATION_ERROR;
+        cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
+        return cs;
+    }
+
+
+    public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
+        return (ObjectType) getType(cpg);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitLoadClass(this);
+        v.visitAllocationInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitCPInstruction(this);
+        v.visitNEW(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/NEWARRAY.java b/java/org/apache/tomcat/util/bcel/generic/NEWARRAY.java
new file mode 100644 (file)
index 0000000..22af18d
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * NEWARRAY -  Create new array of basic type (int, short, ...)
+ * <PRE>Stack: ..., count -&gt; ..., arrayref</PRE>
+ * type must be one of T_INT, T_SHORT, ...
+ * 
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower,
+        StackProducer {
+
+    private byte type;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    NEWARRAY() {
+    }
+
+
+    public NEWARRAY(byte type) {
+        super(org.apache.tomcat.util.bcel.Constants.NEWARRAY, (short) 2);
+        this.type = type;
+    }
+
+
+    public NEWARRAY(BasicType type) {
+        this(type.getType());
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        out.writeByte(type);
+    }
+
+
+    /**
+     * @return numeric code for basic element type
+     */
+    public final byte getTypecode() {
+        return type;
+    }
+
+
+    /**
+     * @return type of constructed array
+     */
+    public final Type getType() {
+        return new ArrayType(BasicType.getType(type), 1);
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + org.apache.tomcat.util.bcel.Constants.TYPE_NAMES[type];
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        type = bytes.readByte();
+        length = 2;
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            org.apache.tomcat.util.bcel.ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION
+        };
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitAllocationInstruction(this);
+        v.visitExceptionThrower(this);
+        v.visitStackProducer(this);
+        v.visitNEWARRAY(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/NOP.java b/java/org/apache/tomcat/util/bcel/generic/NOP.java
new file mode 100644 (file)
index 0000000..d9f3f5e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * NOP - Do nothing
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class NOP extends Instruction {
+
+    public NOP() {
+        super(org.apache.tomcat.util.bcel.Constants.NOP, (short) 1);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitNOP(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/NamedAndTyped.java b/java/org/apache/tomcat/util/bcel/generic/NamedAndTyped.java
new file mode 100644 (file)
index 0000000..68bbce2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote entity that has both name and type. This is true for local variables,
+ * methods and fields.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface NamedAndTyped {
+
+    public String getName();
+
+
+    public Type getType();
+
+
+    public void setName( String name );
+
+
+    public void setType( Type type );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ObjectType.java b/java/org/apache/tomcat/util/bcel/generic/ObjectType.java
new file mode 100644 (file)
index 0000000..7d7d803
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.Repository;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/** 
+ * Denotes reference such as java.lang.String.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ObjectType extends ReferenceType {
+
+    private String class_name; // Class name of type
+
+
+    /**
+     * @param class_name fully qualified class name, e.g. java.lang.String
+     */
+    public ObjectType(String class_name) {
+        super(Constants.T_REFERENCE, "L" + class_name.replace('.', '/') + ";");
+        this.class_name = class_name.replace('/', '.');
+    }
+
+
+    /** @return name of referenced class
+     */
+    public String getClassName() {
+        return class_name;
+    }
+
+
+    /** @return a hash code value for the object.
+     */
+    public int hashCode() {
+        return class_name.hashCode();
+    }
+
+
+    /** @return true if both type objects refer to the same class.
+     */
+    public boolean equals( Object type ) {
+        return (type instanceof ObjectType)
+                ? ((ObjectType) type).class_name.equals(class_name)
+                : false;
+    }
+
+
+    /**
+     * If "this" doesn't reference a class, it references an interface
+     * or a non-existant entity.
+     * @deprecated this method returns an inaccurate result
+     *   if the class or interface referenced cannot
+     *   be found: use referencesClassExact() instead
+     */
+    public boolean referencesClass() {
+        try {
+            JavaClass jc = Repository.lookupClass(class_name);
+            return jc.isClass();
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+
+    /**
+     * If "this" doesn't reference an interface, it references a class
+     * or a non-existant entity.
+     * @deprecated this method returns an inaccurate result
+     *   if the class or interface referenced cannot
+     *   be found: use referencesInterfaceExact() instead
+     */
+    public boolean referencesInterface() {
+        try {
+            JavaClass jc = Repository.lookupClass(class_name);
+            return !jc.isClass();
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+
+    /**
+     * Return true if this type references a class,
+     * false if it references an interface.
+     * @return true if the type references a class, false if
+     *   it references an interface
+     * @throws ClassNotFoundException if the class or interface
+     *   referenced by this type can't be found
+     */
+    public boolean referencesClassExact() throws ClassNotFoundException {
+        JavaClass jc = Repository.lookupClass(class_name);
+        return jc.isClass();
+    }
+
+
+    /**
+     * Return true if this type references an interface,
+     * false if it references a class.
+     * @return true if the type references an interface, false if
+     *   it references a class
+     * @throws ClassNotFoundException if the class or interface
+     *   referenced by this type can't be found
+     */
+    public boolean referencesInterfaceExact() throws ClassNotFoundException {
+        JavaClass jc = Repository.lookupClass(class_name);
+        return !jc.isClass();
+    }
+
+
+    /**
+     * Return true if this type is a subclass of given ObjectType.
+     * @throws ClassNotFoundException if any of this class's superclasses
+     *  can't be found
+     */
+    public boolean subclassOf( ObjectType superclass ) throws ClassNotFoundException {
+        if (this.referencesInterface() || superclass.referencesInterface()) {
+            return false;
+        }
+        return Repository.instanceOf(this.class_name, superclass.class_name);
+    }
+
+
+    /**
+     * Java Virtual Machine Specification edition 2, ï¿½ 5.4.4 Access Control
+     * @throws ClassNotFoundException if the class referenced by this type
+     *   can't be found
+     */
+    public boolean accessibleTo( ObjectType accessor ) throws ClassNotFoundException {
+        JavaClass jc = Repository.lookupClass(class_name);
+        if (jc.isPublic()) {
+            return true;
+        } else {
+            JavaClass acc = Repository.lookupClass(accessor.class_name);
+            return acc.getPackageName().equals(jc.getPackageName());
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/POP.java b/java/org/apache/tomcat/util/bcel/generic/POP.java
new file mode 100644 (file)
index 0000000..4ca24dc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * POP - Pop top operand stack word
+ *
+ * <PRE>Stack: ..., word -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class POP extends StackInstruction implements PopInstruction {
+
+    public POP() {
+        super(org.apache.tomcat.util.bcel.Constants.POP);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitPopInstruction(this);
+        v.visitStackInstruction(this);
+        v.visitPOP(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/POP2.java b/java/org/apache/tomcat/util/bcel/generic/POP2.java
new file mode 100644 (file)
index 0000000..ebfd6ad
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * POP2 - Pop two top operand stack words
+ *
+ * <PRE>Stack: ..., word2, word1 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class POP2 extends StackInstruction implements PopInstruction {
+
+    public POP2() {
+        super(org.apache.tomcat.util.bcel.Constants.POP2);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitPopInstruction(this);
+        v.visitStackInstruction(this);
+        v.visitPOP2(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/PUSH.java b/java/org/apache/tomcat/util/bcel/generic/PUSH.java
new file mode 100644 (file)
index 0000000..d5c1329
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Wrapper class for push operations, which are implemented either as BIPUSH,
+ * LDC or xCONST_n instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class PUSH implements CompoundInstruction, VariableLengthInstruction,
+        InstructionConstants {
+
+    private Instruction instruction;
+
+
+    /**
+     * This constructor also applies for values of type short, char, byte 
+     *
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, int value) {
+        if ((value >= -1) && (value <= 5)) {
+            instruction = INSTRUCTIONS[Constants.ICONST_0 + value];
+        } else if ((value >= -128) && (value <= 127)) {
+            instruction = new BIPUSH((byte) value);
+        } else if ((value >= -32768) && (value <= 32767)) {
+            instruction = new SIPUSH((short) value);
+        } else {
+            instruction = new LDC(cp.addInteger(value));
+        }
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, boolean value) {
+        instruction = INSTRUCTIONS[Constants.ICONST_0 + (value ? 1 : 0)];
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, float value) {
+        if (value == 0.0) {
+            instruction = FCONST_0;
+        } else if (value == 1.0) {
+            instruction = FCONST_1;
+        } else if (value == 2.0) {
+            instruction = FCONST_2;
+        } else {
+            instruction = new LDC(cp.addFloat(value));
+        }
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, long value) {
+        if (value == 0) {
+            instruction = LCONST_0;
+        } else if (value == 1) {
+            instruction = LCONST_1;
+        } else {
+            instruction = new LDC2_W(cp.addLong(value));
+        }
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, double value) {
+        if (value == 0.0) {
+            instruction = DCONST_0;
+        } else if (value == 1.0) {
+            instruction = DCONST_1;
+        } else {
+            instruction = new LDC2_W(cp.addDouble(value));
+        }
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, String value) {
+        if (value == null) {
+            instruction = ACONST_NULL;
+        } else {
+            instruction = new LDC(cp.addString(value));
+        }
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, Number value) {
+        if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) {
+            instruction = new PUSH(cp, value.intValue()).instruction;
+        } else if (value instanceof Double) {
+            instruction = new PUSH(cp, value.doubleValue()).instruction;
+        } else if (value instanceof Float) {
+            instruction = new PUSH(cp, value.floatValue()).instruction;
+        } else if (value instanceof Long) {
+            instruction = new PUSH(cp, value.longValue()).instruction;
+        } else {
+            throw new ClassGenException("What's this: " + value);
+        }
+    }
+
+
+    /**
+     * creates a push object from a Character value. Warning: Make sure not to attempt to allow
+     * autoboxing to create this value parameter, as an alternative constructor will be called
+     * 
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, Character value) {
+        this(cp, value.charValue());
+    }
+
+
+    /**
+     * @param cp Constant pool
+     * @param value to be pushed 
+     */
+    public PUSH(ConstantPoolGen cp, Boolean value) {
+        this(cp, value.booleanValue());
+    }
+
+
+    public final InstructionList getInstructionList() {
+        return new InstructionList(instruction);
+    }
+
+
+    public final Instruction getInstruction() {
+        return instruction;
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString() {
+        return instruction.toString() + " (PUSH)";
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/PUTFIELD.java b/java/org/apache/tomcat/util/bcel/generic/PUTFIELD.java
new file mode 100644 (file)
index 0000000..133e836
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * PUTFIELD - Put field in object
+ * <PRE>Stack: ..., objectref, value -&gt; ...</PRE>
+ * OR
+ * <PRE>Stack: ..., objectref, value.word1, value.word2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    PUTFIELD() {
+    }
+
+
+    public PUTFIELD(int index) {
+        super(Constants.PUTFIELD, index);
+    }
+
+
+    public int consumeStack( ConstantPoolGen cpg ) {
+        return getFieldSize(cpg) + 1;
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[2 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length + 1] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.NULL_POINTER_EXCEPTION;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackConsumer(this);
+        v.visitPopInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitFieldInstruction(this);
+        v.visitPUTFIELD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/PUTSTATIC.java b/java/org/apache/tomcat/util/bcel/generic/PUTSTATIC.java
new file mode 100644 (file)
index 0000000..3357912
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/** 
+ * PUTSTATIC - Put static field in class
+ * <PRE>Stack: ..., value -&gt; ...</PRE>
+ * OR
+ * <PRE>Stack: ..., value.word1, value.word2 -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    PUTSTATIC() {
+    }
+
+
+    public PUTSTATIC(int index) {
+        super(Constants.PUTSTATIC, index);
+    }
+
+
+    public int consumeStack( ConstantPoolGen cpg ) {
+        return getFieldSize(cpg);
+    }
+
+
+    public Class[] getExceptions() {
+        Class[] cs = new Class[1 + ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_FIELD_AND_METHOD_RESOLUTION.length] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitStackConsumer(this);
+        v.visitPopInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        v.visitFieldInstruction(this);
+        v.visitPUTSTATIC(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/PopInstruction.java b/java/org/apache/tomcat/util/bcel/generic/PopInstruction.java
new file mode 100644 (file)
index 0000000..d3f5d70
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an unparameterized instruction to pop a value on top from the stack,
+ * such as ISTORE, POP, PUTSTATIC.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see ISTORE
+ * @see POP
+ */
+public interface PopInstruction extends StackConsumer {
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/PushInstruction.java b/java/org/apache/tomcat/util/bcel/generic/PushInstruction.java
new file mode 100644 (file)
index 0000000..e3525cb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an unparameterized instruction to produce a value on top of the stack,
+ * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+
+ * @see ILOAD
+ * @see ICONST
+ * @see LDC
+ * @see DUP
+ * @see SIPUSH
+ * @see GETSTATIC
+ */
+public interface PushInstruction extends StackProducer {
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/RET.java b/java/org/apache/tomcat/util/bcel/generic/RET.java
new file mode 100644 (file)
index 0000000..7a14ed6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * RET - Return from subroutine
+ *
+ * <PRE>Stack: ... -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class RET extends Instruction implements IndexedInstruction, TypedInstruction {
+
+    private boolean wide;
+    private int index; // index to local variable containg the return address
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    RET() {
+    }
+
+
+    public RET(int index) {
+        super(org.apache.tomcat.util.bcel.Constants.RET, (short) 2);
+        setIndex(index); // May set wide as side effect
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        if (wide) {
+            out.writeByte(org.apache.tomcat.util.bcel.Constants.WIDE);
+        }
+        out.writeByte(opcode);
+        if (wide) {
+            out.writeShort(index);
+        } else {
+            out.writeByte(index);
+        }
+    }
+
+
+    private final void setWide() {
+        wide = index > org.apache.tomcat.util.bcel.Constants.MAX_BYTE;
+        if (wide) {
+            length = 4; // Including the wide byte  
+        } else {
+            length = 2;
+        }
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        this.wide = wide;
+        if (wide) {
+            index = bytes.readUnsignedShort();
+            length = 4;
+        } else {
+            index = bytes.readUnsignedByte();
+            length = 2;
+        }
+    }
+
+
+    /**
+     * @return index of local variable containg the return address
+     */
+    public final int getIndex() {
+        return index;
+    }
+
+
+    /**
+     * Set index of local variable containg the return address
+     */
+    public final void setIndex( int n ) {
+        if (n < 0) {
+            throw new ClassGenException("Negative index value: " + n);
+        }
+        index = n;
+        setWide();
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + index;
+    }
+
+
+    /** @return return address type
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return ReturnaddressType.NO_TARGET;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitRET(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/RETURN.java b/java/org/apache/tomcat/util/bcel/generic/RETURN.java
new file mode 100644 (file)
index 0000000..afb438b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * RETURN -  Return from void method
+ * <PRE>Stack: ... -&gt; &lt;empty&gt;</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class RETURN extends ReturnInstruction {
+
+    public RETURN() {
+        super(org.apache.tomcat.util.bcel.Constants.RETURN);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitReturnInstruction(this);
+        v.visitRETURN(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ReferenceType.java b/java/org/apache/tomcat/util/bcel/generic/ReferenceType.java
new file mode 100644 (file)
index 0000000..f9cab4c
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.Repository;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/**
+ * Super class for object and array types.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class ReferenceType extends Type {
+
+    protected ReferenceType(byte t, String s) {
+        super(t, s);
+    }
+
+
+    /** Class is non-abstract but not instantiable from the outside
+     */
+    ReferenceType() {
+        super(Constants.T_OBJECT, "<null object>");
+    }
+
+
+    /**
+     * Return true iff this type is castable to another type t as defined in
+     * the JVM specification.  The case where this is Type.NULL is not
+     * defined (see the CHECKCAST definition in the JVM specification).
+     * However, because e.g. CHECKCAST doesn't throw a
+     * ClassCastException when casting a null reference to any Object,
+     * true is returned in this case.
+     *
+     * @throws ClassNotFoundException if any classes or interfaces required
+     *  to determine assignment compatibility can't be found
+     */
+    public boolean isCastableTo( Type t ) throws ClassNotFoundException {
+        if (this.equals(Type.NULL)) {
+            return true; // If this is ever changed in isAssignmentCompatible()
+        }
+        return isAssignmentCompatibleWith(t);
+        /* Yes, it's true: It's the same definition.
+         * See vmspec2 AASTORE / CHECKCAST definitions.
+         */
+    }
+
+
+    /**
+     * Return true iff this is assignment compatible with another type t
+     * as defined in the JVM specification; see the AASTORE definition
+     * there.
+     * @throws ClassNotFoundException if any classes or interfaces required
+     *  to determine assignment compatibility can't be found
+     */
+    public boolean isAssignmentCompatibleWith( Type t ) throws ClassNotFoundException {
+        if (!(t instanceof ReferenceType)) {
+            return false;
+        }
+        ReferenceType T = (ReferenceType) t;
+        if (this.equals(Type.NULL)) {
+            return true; // This is not explicitely stated, but clear. Isn't it?
+        }
+        /* If this is a class type then
+         */
+        if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) {
+            /* If T is a class type, then this must be the same class as T,
+             or this must be a subclass of T;
+             */
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) {
+                if (this.equals(T)) {
+                    return true;
+                }
+                if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T)
+                        .getClassName())) {
+                    return true;
+                }
+            }
+            /* If T is an interface type, this must implement interface T.
+             */
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) {
+                if (Repository.implementationOf(((ObjectType) this).getClassName(),
+                        ((ObjectType) T).getClassName())) {
+                    return true;
+                }
+            }
+        }
+        /* If this is an interface type, then:
+         */
+        if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) {
+            /* If T is a class type, then T must be Object (�2.4.7).
+             */
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) {
+                if (T.equals(Type.OBJECT)) {
+                    return true;
+                }
+            }
+            /* If T is an interface type, then T must be the same interface
+             * as this or a superinterface of this (�2.13.2).
+             */
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) {
+                if (this.equals(T)) {
+                    return true;
+                }
+                if (Repository.implementationOf(((ObjectType) this).getClassName(),
+                        ((ObjectType) T).getClassName())) {
+                    return true;
+                }
+            }
+        }
+        /* If this is an array type, namely, the type SC[], that is, an
+         * array of components of type SC, then:
+         */
+        if (this instanceof ArrayType) {
+            /* If T is a class type, then T must be Object (�2.4.7).
+             */
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) {
+                if (T.equals(Type.OBJECT)) {
+                    return true;
+                }
+            }
+            /* If T is an array type TC[], that is, an array of components
+             * of type TC, then one of the following must be true:
+             */
+            if (T instanceof ArrayType) {
+                /* TC and SC are the same primitive type (�2.4.1).
+                 */
+                Type sc = ((ArrayType) this).getElementType();
+                Type tc = ((ArrayType) T).getElementType();
+                if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) {
+                    return true;
+                }
+                /* TC and SC are reference types (�2.4.6), and type SC is
+                 * assignable to TC by these runtime rules.
+                 */
+                if (tc instanceof ReferenceType && sc instanceof ReferenceType
+                        && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) {
+                    return true;
+                }
+            }
+            /* If T is an interface type, T must be one of the interfaces implemented by arrays (�2.15). */
+            // TODO: Check if this is still valid or find a way to dynamically find out which
+            // interfaces arrays implement. However, as of the JVM specification edition 2, there
+            // are at least two different pages where assignment compatibility is defined and
+            // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or
+            // 'java.io.Serializable'"
+            if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) {
+                for (int ii = 0; ii < Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS.length; ii++) {
+                    if (T.equals(new ObjectType(Constants.INTERFACES_IMPLEMENTED_BY_ARRAYS[ii]))) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false; // default.
+    }
+
+
+    /**
+     * This commutative operation returns the first common superclass (narrowest ReferenceType
+     * referencing a class, not an interface).
+     * If one of the types is a superclass of the other, the former is returned.
+     * If "this" is Type.NULL, then t is returned.
+     * If t is Type.NULL, then "this" is returned.
+     * If "this" equals t ['this.equals(t)'] "this" is returned.
+     * If "this" or t is an ArrayType, then Type.OBJECT is returned;
+     * unless their dimensions match. Then an ArrayType of the same
+     * number of dimensions is returned, with its basic type being the
+     * first common super class of the basic types of "this" and t.
+     * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned.
+     * If not all of the two classes' superclasses cannot be found, "null" is returned.
+     * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier".
+     *
+     * @throws ClassNotFoundException on failure to find superclasses of this
+     *  type, or the type passed as a parameter
+     */
+    public ReferenceType getFirstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException {
+        if (this.equals(Type.NULL)) {
+            return t;
+        }
+        if (t.equals(Type.NULL)) {
+            return this;
+        }
+        if (this.equals(t)) {
+            return this;
+            /*
+             * TODO: Above sounds a little arbitrary. On the other hand, there is
+             * no object referenced by Type.NULL so we can also say all the objects
+             * referenced by Type.NULL were derived from java.lang.Object.
+             * However, the Java Language's "instanceof" operator proves us wrong:
+             * "null" is not referring to an instance of java.lang.Object :)
+             */
+        }
+        /* This code is from a bug report by Konstantin Shagin <konst@cs.technion.ac.il> */
+        if ((this instanceof ArrayType) && (t instanceof ArrayType)) {
+            ArrayType arrType1 = (ArrayType) this;
+            ArrayType arrType2 = (ArrayType) t;
+            if ((arrType1.getDimensions() == arrType2.getDimensions())
+                    && arrType1.getBasicType() instanceof ObjectType
+                    && arrType2.getBasicType() instanceof ObjectType) {
+                return new ArrayType(((ObjectType) arrType1.getBasicType())
+                        .getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), arrType1
+                        .getDimensions());
+            }
+        }
+        if ((this instanceof ArrayType) || (t instanceof ArrayType)) {
+            return Type.OBJECT;
+            // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType?
+        }
+        if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface())
+                || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) {
+            return Type.OBJECT;
+            // TODO: The above line is correct comparing to the vmspec2. But one could
+            // make class file verification a bit stronger here by using the notion of
+            // superinterfaces or even castability or assignment compatibility.
+        }
+        // this and t are ObjectTypes, see above.
+        ObjectType thiz = (ObjectType) this;
+        ObjectType other = (ObjectType) t;
+        JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName());
+        JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName());
+        if ((thiz_sups == null) || (other_sups == null)) {
+            return null;
+        }
+        // Waaahh...
+        JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1];
+        JavaClass[] t_sups = new JavaClass[other_sups.length + 1];
+        System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length);
+        System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length);
+        this_sups[0] = Repository.lookupClass(thiz.getClassName());
+        t_sups[0] = Repository.lookupClass(other.getClassName());
+        for (int i = 0; i < t_sups.length; i++) {
+            for (int j = 0; j < this_sups.length; j++) {
+                if (this_sups[j].equals(t_sups[i])) {
+                    return new ObjectType(this_sups[j].getClassName());
+                }
+            }
+        }
+        // Huh? Did you ask for Type.OBJECT's superclass??
+        return null;
+    }
+
+
+    /**
+     * This commutative operation returns the first common superclass (narrowest ReferenceType
+     * referencing a class, not an interface).
+     * If one of the types is a superclass of the other, the former is returned.
+     * If "this" is Type.NULL, then t is returned.
+     * If t is Type.NULL, then "this" is returned.
+     * If "this" equals t ['this.equals(t)'] "this" is returned.
+     * If "this" or t is an ArrayType, then Type.OBJECT is returned.
+     * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned.
+     * If not all of the two classes' superclasses cannot be found, "null" is returned.
+     * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier".
+     *
+     * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has
+     *             slightly changed semantics.
+     * @throws ClassNotFoundException on failure to find superclasses of this
+     *  type, or the type passed as a parameter
+     */
+    public ReferenceType firstCommonSuperclass( ReferenceType t ) throws ClassNotFoundException {
+        if (this.equals(Type.NULL)) {
+            return t;
+        }
+        if (t.equals(Type.NULL)) {
+            return this;
+        }
+        if (this.equals(t)) {
+            return this;
+            /*
+             * TODO: Above sounds a little arbitrary. On the other hand, there is
+             * no object referenced by Type.NULL so we can also say all the objects
+             * referenced by Type.NULL were derived from java.lang.Object.
+             * However, the Java Language's "instanceof" operator proves us wrong:
+             * "null" is not referring to an instance of java.lang.Object :)
+             */
+        }
+        if ((this instanceof ArrayType) || (t instanceof ArrayType)) {
+            return Type.OBJECT;
+            // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType?
+        }
+        if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface())
+                || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) {
+            return Type.OBJECT;
+            // TODO: The above line is correct comparing to the vmspec2. But one could
+            // make class file verification a bit stronger here by using the notion of
+            // superinterfaces or even castability or assignment compatibility.
+        }
+        // this and t are ObjectTypes, see above.
+        ObjectType thiz = (ObjectType) this;
+        ObjectType other = (ObjectType) t;
+        JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName());
+        JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName());
+        if ((thiz_sups == null) || (other_sups == null)) {
+            return null;
+        }
+        // Waaahh...
+        JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1];
+        JavaClass[] t_sups = new JavaClass[other_sups.length + 1];
+        System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length);
+        System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length);
+        this_sups[0] = Repository.lookupClass(thiz.getClassName());
+        t_sups[0] = Repository.lookupClass(other.getClassName());
+        for (int i = 0; i < t_sups.length; i++) {
+            for (int j = 0; j < this_sups.length; j++) {
+                if (this_sups[j].equals(t_sups[i])) {
+                    return new ObjectType(this_sups[j].getClassName());
+                }
+            }
+        }
+        // Huh? Did you ask for Type.OBJECT's superclass??
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ReturnInstruction.java b/java/org/apache/tomcat/util/bcel/generic/ReturnInstruction.java
new file mode 100644 (file)
index 0000000..63eba56
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.ExceptionConstants;
+
+/**
+ * Super class for the xRETURN family of instructions.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class ReturnInstruction extends Instruction implements ExceptionThrower,
+        TypedInstruction, StackConsumer {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    ReturnInstruction() {
+    }
+
+
+    /**
+     * @param opcode of instruction
+     */
+    protected ReturnInstruction(short opcode) {
+        super(opcode, (short) 1);
+    }
+
+
+    public Type getType() {
+        switch (opcode) {
+            case Constants.IRETURN:
+                return Type.INT;
+            case Constants.LRETURN:
+                return Type.LONG;
+            case Constants.FRETURN:
+                return Type.FLOAT;
+            case Constants.DRETURN:
+                return Type.DOUBLE;
+            case Constants.ARETURN:
+                return Type.OBJECT;
+            case Constants.RETURN:
+                return Type.VOID;
+            default: // Never reached
+                throw new ClassGenException("Unknown type " + opcode);
+        }
+    }
+
+
+    public Class[] getExceptions() {
+        return new Class[] {
+            ExceptionConstants.ILLEGAL_MONITOR_STATE
+        };
+    }
+
+
+    /** @return type associated with the instruction
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return getType();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/ReturnaddressType.java b/java/org/apache/tomcat/util/bcel/generic/ReturnaddressType.java
new file mode 100644 (file)
index 0000000..aacf3e8
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import org.apache.tomcat.util.bcel.Constants;
+
+/** 
+ * Returnaddress, the type JSR or JSR_W instructions push upon the stack.
+ *
+ * see vmspec2 ï¿½3.3.3
+ * @version $Id$
+ * @author Enver Haase
+ */
+public class ReturnaddressType extends Type {
+
+    public static final ReturnaddressType NO_TARGET = new ReturnaddressType();
+    private InstructionHandle returnTarget;
+
+
+    /**
+     * A Returnaddress [that doesn't know where to return to].
+     */
+    private ReturnaddressType() {
+        super(Constants.T_ADDRESS, "<return address>");
+    }
+
+
+    /**
+     * Creates a ReturnaddressType object with a target.
+     */
+    public ReturnaddressType(InstructionHandle returnTarget) {
+        super(Constants.T_ADDRESS, "<return address targeting " + returnTarget + ">");
+        this.returnTarget = returnTarget;
+    }
+
+
+    /** @return a hash code value for the object.
+     */
+    public int hashCode() {
+        if (returnTarget == null) {
+            return 0;
+        }
+        return returnTarget.hashCode();
+    }
+
+
+    /**
+     * Returns if the two Returnaddresses refer to the same target.
+     */
+    public boolean equals( Object rat ) {
+        if (!(rat instanceof ReturnaddressType)) {
+            return false;
+        }
+        ReturnaddressType that = (ReturnaddressType) rat;
+        if (this.returnTarget == null || that.returnTarget == null) {
+            return that.returnTarget == this.returnTarget;
+        }
+        return that.returnTarget.equals(this.returnTarget);
+    }
+
+
+    /**
+     * @return the target of this ReturnaddressType
+     */
+    public InstructionHandle getTarget() {
+        return returnTarget;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SALOAD.java b/java/org/apache/tomcat/util/bcel/generic/SALOAD.java
new file mode 100644 (file)
index 0000000..bf7a69f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * SALOAD - Load short from array
+ * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class SALOAD extends ArrayInstruction implements StackProducer {
+
+    public SALOAD() {
+        super(org.apache.tomcat.util.bcel.Constants.SALOAD);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackProducer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitSALOAD(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SASTORE.java b/java/org/apache/tomcat/util/bcel/generic/SASTORE.java
new file mode 100644 (file)
index 0000000..f6908f7
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * SASTORE - Store into short array
+ * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class SASTORE extends ArrayInstruction implements StackConsumer {
+
+    public SASTORE() {
+        super(org.apache.tomcat.util.bcel.Constants.SASTORE);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitArrayInstruction(this);
+        v.visitSASTORE(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SIPUSH.java b/java/org/apache/tomcat/util/bcel/generic/SIPUSH.java
new file mode 100644 (file)
index 0000000..890d8dd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/**
+ * SIPUSH - Push short
+ *
+ * <PRE>Stack: ... -&gt; ..., value</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class SIPUSH extends Instruction implements ConstantPushInstruction {
+
+    private short b;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    SIPUSH() {
+    }
+
+
+    public SIPUSH(short b) {
+        super(org.apache.tomcat.util.bcel.Constants.SIPUSH, (short) 3);
+        this.b = b;
+    }
+
+
+    /**
+     * Dump instruction as short code to stream out.
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        super.dump(out);
+        out.writeShort(b);
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        return super.toString(verbose) + " " + b;
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        length = 3;
+        b = bytes.readShort();
+    }
+
+
+    public Number getValue() {
+        return new Integer(b);
+    }
+
+
+    /** @return Type.SHORT
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.SHORT;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitPushInstruction(this);
+        v.visitStackProducer(this);
+        v.visitTypedInstruction(this);
+        v.visitConstantPushInstruction(this);
+        v.visitSIPUSH(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SWAP.java b/java/org/apache/tomcat/util/bcel/generic/SWAP.java
new file mode 100644 (file)
index 0000000..71ced13
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * SWAP - Swa top operand stack word
+ * <PRE>Stack: ..., word2, word1 -&gt; ..., word1, word2</PRE>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class SWAP extends StackInstruction implements StackConsumer, StackProducer {
+
+    public SWAP() {
+        super(org.apache.tomcat.util.bcel.Constants.SWAP);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitStackInstruction(this);
+        v.visitSWAP(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SWITCH.java b/java/org/apache/tomcat/util/bcel/generic/SWITCH.java
new file mode 100644 (file)
index 0000000..b9ea7e0
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/** 
+ * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or
+ * TABLESWITCH instruction, depending on whether the match values (int[]) can be
+ * sorted with no gaps between the numbers.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class SWITCH implements CompoundInstruction {
+
+    private int[] match;
+    private InstructionHandle[] targets;
+    private Select instruction;
+    private int match_length;
+
+
+    /**
+     * Template for switch() constructs. If the match array can be
+     * sorted in ascending order with gaps no larger than max_gap
+     * between the numbers, a TABLESWITCH instruction is generated, and
+     * a LOOKUPSWITCH otherwise. The former may be more efficient, but
+     * needs more space.
+     * 
+     * Note, that the key array always will be sorted, though we leave
+     * the original arrays unaltered.
+     *
+     * @param match array of match values (case 2: ... case 7: ..., etc.)
+     * @param targets the instructions to be branched to for each case
+     * @param target the default target
+     * @param max_gap maximum gap that may between case branches
+     */
+    public SWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target, int max_gap) {
+        this.match = (int[]) match.clone();
+        this.targets = (InstructionHandle[]) targets.clone();
+        if ((match_length = match.length) < 2) {
+            instruction = new TABLESWITCH(match, targets, target);
+        } else {
+            sort(0, match_length - 1);
+            if (matchIsOrdered(max_gap)) {
+                fillup(max_gap, target);
+                instruction = new TABLESWITCH(this.match, this.targets, target);
+            } else {
+                instruction = new LOOKUPSWITCH(this.match, this.targets, target);
+            }
+        }
+    }
+
+
+    public SWITCH(int[] match, InstructionHandle[] targets, InstructionHandle target) {
+        this(match, targets, target, 1);
+    }
+
+
+    private final void fillup( int max_gap, InstructionHandle target ) {
+        int max_size = match_length + match_length * max_gap;
+        int[] m_vec = new int[max_size];
+        InstructionHandle[] t_vec = new InstructionHandle[max_size];
+        int count = 1;
+        m_vec[0] = match[0];
+        t_vec[0] = targets[0];
+        for (int i = 1; i < match_length; i++) {
+            int prev = match[i - 1];
+            int gap = match[i] - prev;
+            for (int j = 1; j < gap; j++) {
+                m_vec[count] = prev + j;
+                t_vec[count] = target;
+                count++;
+            }
+            m_vec[count] = match[i];
+            t_vec[count] = targets[i];
+            count++;
+        }
+        match = new int[count];
+        targets = new InstructionHandle[count];
+        System.arraycopy(m_vec, 0, match, 0, count);
+        System.arraycopy(t_vec, 0, targets, 0, count);
+    }
+
+
+    /**
+     * Sort match and targets array with QuickSort.
+     */
+    private final void sort( int l, int r ) {
+        int i = l, j = r;
+        int h, m = match[(l + r) / 2];
+        InstructionHandle h2;
+        do {
+            while (match[i] < m) {
+                i++;
+            }
+            while (m < match[j]) {
+                j--;
+            }
+            if (i <= j) {
+                h = match[i];
+                match[i] = match[j];
+                match[j] = h; // Swap elements
+                h2 = targets[i];
+                targets[i] = targets[j];
+                targets[j] = h2; // Swap instructions, too
+                i++;
+                j--;
+            }
+        } while (i <= j);
+        if (l < j) {
+            sort(l, j);
+        }
+        if (i < r) {
+            sort(i, r);
+        }
+    }
+
+
+    /**
+     * @return match is sorted in ascending order with no gap bigger than max_gap?
+     */
+    private final boolean matchIsOrdered( int max_gap ) {
+        for (int i = 1; i < match_length; i++) {
+            if (match[i] - match[i - 1] > max_gap) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    public final InstructionList getInstructionList() {
+        return new InstructionList(instruction);
+    }
+
+
+    public final Instruction getInstruction() {
+        return instruction;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/Select.java b/java/org/apache/tomcat/util/bcel/generic/Select.java
new file mode 100644 (file)
index 0000000..aef247c
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions.
+ * 
+ * <p>We use our super's <code>target</code> property as the default target.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see LOOKUPSWITCH
+ * @see TABLESWITCH
+ * @see InstructionList
+ */
+public abstract class Select extends BranchInstruction implements VariableLengthInstruction,
+        StackProducer {
+
+    protected int[] match; // matches, i.e., case 1: ...
+    protected int[] indices; // target offsets
+    protected InstructionHandle[] targets; // target objects in instruction list
+    protected int fixed_length; // fixed length defined by subclasses
+    protected int match_length; // number of cases
+    protected int padding = 0; // number of pad bytes for alignment
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    Select() {
+    }
+
+
+    /**
+     * (Match, target) pairs for switch.
+     * `Match' and `targets' must have the same length of course.
+     *
+     * @param match array of matching values
+     * @param targets instruction targets
+     * @param defaultTarget default instruction target
+     */
+    Select(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) {
+        super(opcode, defaultTarget);
+        this.targets = targets;
+        for (int i = 0; i < targets.length; i++) {
+            notifyTarget(null, targets[i], this);
+        }
+        this.match = match;
+        if ((match_length = match.length) != targets.length) {
+            throw new ClassGenException("Match and target array have not the same length: Match length: " + match.length + " Target length: " + targets.length);
+        }
+        indices = new int[match_length];
+    }
+
+
+    /**
+     * Since this is a variable length instruction, it may shift the following
+     * instructions which then need to update their position.
+     *
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
+     *
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
+     */
+    protected int updatePosition( int offset, int max_offset ) {
+        position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc.
+        short old_length = length;
+        /* Alignment on 4-byte-boundary, + 1, because of tag byte.
+         */
+        padding = (4 - ((position + 1) % 4)) % 4;
+        length = (short) (fixed_length + padding); // Update length
+        return length - old_length;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        out.writeByte(opcode);
+        for (int i = 0; i < padding; i++) {
+            out.writeByte(0);
+        }
+        index = getTargetOffset(); // Write default target offset
+        out.writeInt(index);
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes
+        for (int i = 0; i < padding; i++) {
+            bytes.readByte();
+        }
+        // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH)
+        index = bytes.readInt();
+    }
+
+
+    /**
+     * @return mnemonic for instruction
+     */
+    public String toString( boolean verbose ) {
+        StringBuffer buf = new StringBuffer(super.toString(verbose));
+        if (verbose) {
+            for (int i = 0; i < match_length; i++) {
+                String s = "null";
+                if (targets[i] != null) {
+                    s = targets[i].getInstruction().toString();
+                }
+                buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append(
+                        indices[i]).append("})");
+            }
+        } else {
+            buf.append(" ...");
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * Set branch target for `i'th case
+     */
+    public void setTarget( int i, InstructionHandle target ) {
+        notifyTarget(targets[i], target, this);
+        targets[i] = target;
+    }
+
+
+    /**
+     * @param old_ih old target
+     * @param new_ih new target
+     */
+    public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
+        boolean targeted = false;
+        if (target == old_ih) {
+            targeted = true;
+            setTarget(new_ih);
+        }
+        for (int i = 0; i < targets.length; i++) {
+            if (targets[i] == old_ih) {
+                targeted = true;
+                setTarget(i, new_ih);
+            }
+        }
+        if (!targeted) {
+            throw new ClassGenException("Not targeting " + old_ih);
+        }
+    }
+
+
+    /**
+     * @return true, if ih is target of this instruction
+     */
+    public boolean containsTarget( InstructionHandle ih ) {
+        if (target == ih) {
+            return true;
+        }
+        for (int i = 0; i < targets.length; i++) {
+            if (targets[i] == ih) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    protected Object clone() throws CloneNotSupportedException {
+        Select copy = (Select) super.clone();
+        copy.match = (int[]) match.clone();
+        copy.indices = (int[]) indices.clone();
+        copy.targets = (InstructionHandle[]) targets.clone();
+        return copy;
+    }
+
+
+    /**
+     * Inform targets that they're not targeted anymore.
+     */
+    void dispose() {
+        super.dispose();
+        for (int i = 0; i < targets.length; i++) {
+            targets[i].removeTargeter(this);
+        }
+    }
+
+
+    /**
+     * @return array of match indices
+     */
+    public int[] getMatchs() {
+        return match;
+    }
+
+
+    /**
+     * @return array of match target offsets
+     */
+    public int[] getIndices() {
+        return indices;
+    }
+
+
+    /**
+     * @return array of match targets
+     */
+    public InstructionHandle[] getTargets() {
+        return targets;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/SimpleElementValueGen.java b/java/org/apache/tomcat/util/bcel/generic/SimpleElementValueGen.java
new file mode 100644 (file)
index 0000000..e1ae11b
--- /dev/null
@@ -0,0 +1,245 @@
+package org.apache.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.classfile.ConstantDouble;
+import org.apache.tomcat.util.bcel.classfile.ConstantFloat;
+import org.apache.tomcat.util.bcel.classfile.ConstantInteger;
+import org.apache.tomcat.util.bcel.classfile.ConstantLong;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ElementValue;
+import org.apache.tomcat.util.bcel.classfile.SimpleElementValue;
+
+public class SimpleElementValueGen extends ElementValueGen
+{
+       // For primitive types and string type, this points to the value entry in
+       // the cpGen
+       // For 'class' this points to the class entry in the cpGen
+       private int idx;
+
+       // ctors for each supported type... type could be inferred but for now lets
+       // force it to be passed
+       /**
+        * Protected ctor used for deserialization, doesn't *put* an entry in the
+        * constant pool, assumes the one at the supplied index is correct.
+        */
+       protected SimpleElementValueGen(int type, int idx, ConstantPoolGen cpGen)
+       {
+               super(type, cpGen);
+               this.idx = idx;
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, int value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addInteger(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, long value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addLong(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, double value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addDouble(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, float value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addFloat(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, short value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addInteger(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, byte value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addInteger(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, char value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addInteger(value);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, boolean value)
+       {
+               super(type, cpGen);
+               if (value)
+                       idx = cpGen.addInteger(1);
+               else
+                       idx = cpGen.addInteger(0);
+       }
+
+       public SimpleElementValueGen(int type, ConstantPoolGen cpGen, String value)
+       {
+               super(type, cpGen);
+               idx = cpGen.addUtf8(value);
+       }
+
+       /**
+        * The boolean controls whether we copy info from the 'old' constant pool to
+        * the 'new'. You need to use this ctor if the annotation is being copied
+        * from one file to another.
+        */
+       public SimpleElementValueGen(SimpleElementValue value,
+                       ConstantPoolGen cpool, boolean copyPoolEntries)
+       {
+               super(value.getElementValueType(), cpool);
+               if (!copyPoolEntries)
+               {
+                       // J5ASSERT: Could assert value.stringifyValue() is the same as
+                       // cpool.getConstant(SimpleElementValuevalue.getIndex())
+                       idx = value.getIndex();
+               }
+               else
+               {
+                       switch (value.getElementValueType())
+                       {
+                       case STRING:
+                               idx = cpool.addUtf8(value.getValueString());
+                               break;
+                       case PRIMITIVE_INT:
+                               idx = cpool.addInteger(value.getValueInt());
+                               break;
+                       case PRIMITIVE_BYTE:
+                               idx = cpool.addInteger(value.getValueByte());
+                               break;
+                       case PRIMITIVE_CHAR:
+                               idx = cpool.addInteger(value.getValueChar());
+                               break;
+                       case PRIMITIVE_LONG:
+                               idx = cpool.addLong(value.getValueLong());
+                               break;
+                       case PRIMITIVE_FLOAT:
+                               idx = cpool.addFloat(value.getValueFloat());
+                               break;
+                       case PRIMITIVE_DOUBLE:
+                               idx = cpool.addDouble(value.getValueDouble());
+                               break;
+                       case PRIMITIVE_BOOLEAN:
+                               if (value.getValueBoolean())
+                               {
+                                       idx = cpool.addInteger(1);
+                               }
+                               else
+                               {
+                                       idx = cpool.addInteger(0);
+                               }
+                               break;
+                       case PRIMITIVE_SHORT:
+                               idx = cpool.addInteger(value.getValueShort());
+                               break;
+                       default:
+                               throw new RuntimeException(
+                                               "SimpleElementValueGen class does not know how "
+                                                               + "to copy this type " + type);
+                       }
+               }
+       }
+
+       /**
+        * Return immutable variant
+        */
+       public ElementValue getElementValue()
+       {
+               return new SimpleElementValue(type, idx, cpGen.getConstantPool());
+       }
+
+       public int getIndex()
+       {
+               return idx;
+       }
+
+       public String getValueString()
+       {
+               if (type != STRING)
+                       throw new RuntimeException(
+                                       "Dont call getValueString() on a non STRING ElementValue");
+               ConstantUtf8 c = (ConstantUtf8) cpGen.getConstant(idx);
+               return c.getBytes();
+       }
+
+       public int getValueInt()
+       {
+               if (type != PRIMITIVE_INT)
+                       throw new RuntimeException(
+                                       "Dont call getValueString() on a non STRING ElementValue");
+               ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx);
+               return c.getBytes();
+       }
+
+       // Whatever kind of value it is, return it as a string
+       public String stringifyValue()
+       {
+               switch (type)
+               {
+               case PRIMITIVE_INT:
+                       ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx);
+                       return Integer.toString(c.getBytes());
+               case PRIMITIVE_LONG:
+                       ConstantLong j = (ConstantLong) cpGen.getConstant(idx);
+                       return Long.toString(j.getBytes());
+               case PRIMITIVE_DOUBLE:
+                       ConstantDouble d = (ConstantDouble) cpGen.getConstant(idx);
+                       return Double.toString(d.getBytes());
+               case PRIMITIVE_FLOAT:
+                       ConstantFloat f = (ConstantFloat) cpGen.getConstant(idx);
+                       return Float.toString(f.getBytes());
+               case PRIMITIVE_SHORT:
+                       ConstantInteger s = (ConstantInteger) cpGen.getConstant(idx);
+                       return Integer.toString(s.getBytes());
+               case PRIMITIVE_BYTE:
+                       ConstantInteger b = (ConstantInteger) cpGen.getConstant(idx);
+                       return Integer.toString(b.getBytes());
+               case PRIMITIVE_CHAR:
+                       ConstantInteger ch = (ConstantInteger) cpGen.getConstant(idx);
+                       return Integer.toString(ch.getBytes());
+               case PRIMITIVE_BOOLEAN:
+                       ConstantInteger bo = (ConstantInteger) cpGen.getConstant(idx);
+                       if (bo.getBytes() == 0)
+                               return "false";
+                       if (bo.getBytes() != 0)
+                               return "true";
+               case STRING:
+                       ConstantUtf8 cu8 = (ConstantUtf8) cpGen.getConstant(idx);
+                       return cu8.getBytes();
+               default:
+                       throw new RuntimeException(
+                                       "SimpleElementValueGen class does not know how to stringify type "
+                                                       + type);
+               }
+       }
+
+       public void dump(DataOutputStream dos) throws IOException
+       {
+               dos.writeByte(type); // u1 kind of value
+               switch (type)
+               {
+               case PRIMITIVE_INT:
+               case PRIMITIVE_BYTE:
+               case PRIMITIVE_CHAR:
+               case PRIMITIVE_FLOAT:
+               case PRIMITIVE_LONG:
+               case PRIMITIVE_BOOLEAN:
+               case PRIMITIVE_SHORT:
+               case PRIMITIVE_DOUBLE:
+               case STRING:
+                       dos.writeShort(idx);
+                       break;
+               default:
+                       throw new RuntimeException(
+                                       "SimpleElementValueGen doesnt know how to write out type "
+                                                       + type);
+               }
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/StackConsumer.java b/java/org/apache/tomcat/util/bcel/generic/StackConsumer.java
new file mode 100644 (file)
index 0000000..990f575
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote an instruction that may consume a value from the stack.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface StackConsumer {
+
+    /** @return how many words are consumed from stack
+     */
+    public int consumeStack( ConstantPoolGen cpg );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/StackInstruction.java b/java/org/apache/tomcat/util/bcel/generic/StackInstruction.java
new file mode 100644 (file)
index 0000000..5d7bf76
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Super class for stack operations like DUP and POP.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class StackInstruction extends Instruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    StackInstruction() {
+    }
+
+
+    /**
+     * @param opcode instruction opcode
+     */
+    protected StackInstruction(short opcode) {
+        super(opcode, (short) 1);
+    }
+
+
+    /** @return Type.UNKNOWN
+     */
+    public Type getType( ConstantPoolGen cp ) {
+        return Type.UNKNOWN;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/StackProducer.java b/java/org/apache/tomcat/util/bcel/generic/StackProducer.java
new file mode 100644 (file)
index 0000000..04a32be
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denote an instruction that may produce a value on top of the stack
+ * (this excludes DUP_X1, e.g.)
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface StackProducer {
+
+    /** @return how many words are produced on stack
+     */
+    public int produceStack( ConstantPoolGen cpg );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/StoreInstruction.java b/java/org/apache/tomcat/util/bcel/generic/StoreInstruction.java
new file mode 100644 (file)
index 0000000..6ce354f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an unparameterized instruction to store a value into a local variable,
+ * e.g. ISTORE.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     * tag and length are defined in readInstruction and initFromFile, respectively.
+     */
+    StoreInstruction(short canon_tag, short c_tag) {
+        super(canon_tag, c_tag);
+    }
+
+
+    /**
+     * @param opcode Instruction opcode
+     * @param c_tag Instruction number for compact version, ASTORE_0, e.g.
+     * @param n local variable index (unsigned short)
+     */
+    protected StoreInstruction(short opcode, short c_tag, int n) {
+        super(opcode, c_tag, n);
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitStackConsumer(this);
+        v.visitPopInstruction(this);
+        v.visitTypedInstruction(this);
+        v.visitLocalVariableInstruction(this);
+        v.visitStoreInstruction(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/TABLESWITCH.java b/java/org/apache/tomcat/util/bcel/generic/TABLESWITCH.java
new file mode 100644 (file)
index 0000000..15a3f5b
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import org.apache.tomcat.util.bcel.util.ByteSequence;
+
+/** 
+ * TABLESWITCH - Switch within given range of values, i.e., low..high
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see SWITCH
+ */
+public class TABLESWITCH extends Select {
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    TABLESWITCH() {
+    }
+
+
+    /**
+     * @param match sorted array of match values, match[0] must be low value, 
+     * match[match_length - 1] high value
+     * @param targets where to branch for matched values
+     * @param defaultTarget default branch
+     */
+    public TABLESWITCH(int[] match, InstructionHandle[] targets, InstructionHandle defaultTarget) {
+        super(org.apache.tomcat.util.bcel.Constants.TABLESWITCH, match, targets, defaultTarget);
+        length = (short) (13 + match_length * 4); /* Alignment remainder assumed
+         * 0 here, until dump time */
+        fixed_length = length;
+    }
+
+
+    /**
+     * Dump instruction as byte code to stream out.
+     * @param out Output stream
+     */
+    public void dump( DataOutputStream out ) throws IOException {
+        super.dump(out);
+        int low = (match_length > 0) ? match[0] : 0;
+        out.writeInt(low);
+        int high = (match_length > 0) ? match[match_length - 1] : 0;
+        out.writeInt(high);
+        for (int i = 0; i < match_length; i++) {
+            out.writeInt(indices[i] = getTargetOffset(targets[i]));
+        }
+    }
+
+
+    /**
+     * Read needed data (e.g. index) from file.
+     */
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        super.initFromFile(bytes, wide);
+        int low = bytes.readInt();
+        int high = bytes.readInt();
+        match_length = high - low + 1;
+        fixed_length = (short) (13 + match_length * 4);
+        length = (short) (fixed_length + padding);
+        match = new int[match_length];
+        indices = new int[match_length];
+        targets = new InstructionHandle[match_length];
+        for (int i = low; i <= high; i++) {
+            match[i - low] = i;
+        }
+        for (int i = 0; i < match_length; i++) {
+            indices[i] = bytes.readInt();
+        }
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    public void accept( Visitor v ) {
+        v.visitVariableLengthInstruction(this);
+        v.visitStackProducer(this);
+        v.visitBranchInstruction(this);
+        v.visitSelect(this);
+        v.visitTABLESWITCH(this);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/TargetLostException.java b/java/org/apache/tomcat/util/bcel/generic/TargetLostException.java
new file mode 100644 (file)
index 0000000..dd7c993
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Thrown by InstructionList.remove() when one or multiple disposed instruction
+ * are still being referenced by a InstructionTargeter object. I.e. the
+ * InstructionTargeter has to be notified that (one of) the InstructionHandle it
+ * is referencing is being removed from the InstructionList and thus not valid anymore.
+ *
+ * Making this an exception instead of a return value forces the user to handle
+ * these case explicitely in a try { ... } catch. The following code illustrates
+ * how this may be done:
+ *
+ * <PRE>
+ *     ...
+ *     try {
+ *     il.delete(start_ih, end_ih);
+ *     } catch(TargetLostException e) {
+ *       InstructionHandle[] targets = e.getTargets();
+ *      for(int i=0; i < targets.length; i++) {
+ *        InstructionTargeter[] targeters = targets[i].getTargeters();
+ *     
+ *        for(int j=0; j < targeters.length; j++)
+ *          targeters[j].updateTarget(targets[i], new_target);
+ *       }
+ *     }
+ * </PRE>
+ *
+ * @see InstructionHandle
+ * @see InstructionList
+ * @see InstructionTargeter
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class TargetLostException extends Exception {
+
+    private InstructionHandle[] targets;
+
+
+    TargetLostException(InstructionHandle[] t, String mesg) {
+        super(mesg);
+        targets = t;
+    }
+
+
+    /**
+     * @return list of instructions still being targeted.
+     */
+    public InstructionHandle[] getTargets() {
+        return targets;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/Type.java b/java/org/apache/tomcat/util/bcel/generic/Type.java
new file mode 100644 (file)
index 0000000..1c5d513
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.ClassFormatException;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/** 
+ * Abstract super class for all possible java types, namely basic types
+ * such as int, object types like String and array types, e.g. int[]
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public abstract class Type implements java.io.Serializable {
+
+    protected byte type;
+    protected String signature; // signature for the type
+    /** Predefined constants
+     */
+    public static final BasicType VOID = new BasicType(Constants.T_VOID);
+    public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN);
+    public static final BasicType INT = new BasicType(Constants.T_INT);
+    public static final BasicType SHORT = new BasicType(Constants.T_SHORT);
+    public static final BasicType BYTE = new BasicType(Constants.T_BYTE);
+    public static final BasicType LONG = new BasicType(Constants.T_LONG);
+    public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE);
+    public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT);
+    public static final BasicType CHAR = new BasicType(Constants.T_CHAR);
+    public static final ObjectType OBJECT = new ObjectType("java.lang.Object");
+    public static final ObjectType CLASS = new ObjectType("java.lang.Class");
+    public static final ObjectType STRING = new ObjectType("java.lang.String");
+    public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
+    public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
+    public static final Type[] NO_ARGS = new Type[0];
+    public static final ReferenceType NULL = new ReferenceType() {
+    };
+    public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "<unknown object>") {
+    };
+
+
+    protected Type(byte t, String s) {
+        type = t;
+        signature = s;
+    }
+
+
+    /**
+     * @return hashcode of Type
+     */
+    public int hashCode() {
+       return type ^ signature.hashCode();
+    }
+    
+    
+    /**
+     * @return whether the Types are equal
+     */
+    public boolean equals(Object o) {
+               if (o instanceof Type) {
+                       Type t = (Type)o;
+                       return (type == t.type) && signature.equals(t.signature);
+               }
+               return false;
+    }
+    
+    
+    /**
+     * @return signature for given type.
+     */
+    public String getSignature() {
+        return signature;
+    }
+
+
+    /**
+     * @return type as defined in Constants
+     */
+    public byte getType() {
+        return type;
+    }
+
+
+    /**
+     * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
+     */
+    public int getSize() {
+        switch (type) {
+            case Constants.T_DOUBLE:
+            case Constants.T_LONG:
+                return 2;
+            case Constants.T_VOID:
+                return 0;
+            default:
+                return 1;
+        }
+    }
+
+
+    /**
+     * @return Type string, e.g. `int[]'
+     */
+    public String toString() {
+        return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN))) ? signature : Utility
+                .signatureToString(signature, false);
+    }
+
+
+    /**
+     * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
+     * becomes (Ljava/lang/String;)[I
+     *
+     * @param return_type what the method returns
+     * @param arg_types what are the argument types
+     * @return method signature for given type(s).
+     */
+    public static String getMethodSignature( Type return_type, Type[] arg_types ) {
+        StringBuffer buf = new StringBuffer("(");
+        int length = (arg_types == null) ? 0 : arg_types.length;
+        for (int i = 0; i < length; i++) {
+            buf.append(arg_types[i].getSignature());
+        }
+        buf.append(')');
+        buf.append(return_type.getSignature());
+        return buf.toString();
+    }
+
+    private static ThreadLocal consumed_chars = new ThreadLocal() {
+
+        protected Object initialValue() {
+            return new Integer(0);
+        }
+    };//int consumed_chars=0; // Remember position in string, see getArgumentTypes
+
+
+    private static int unwrap( ThreadLocal tl ) {
+        return ((Integer) tl.get()).intValue();
+    }
+
+
+    private static void wrap( ThreadLocal tl, int value ) {
+        tl.set(new Integer(value));
+    }
+
+
+    /**
+     * Convert signature to a Type object.
+     * @param signature signature string such as Ljava/lang/String;
+     * @return type object
+     */
+    public static final Type getType( String signature ) throws StringIndexOutOfBoundsException {
+        byte type = Utility.typeOfSignature(signature);
+        if (type <= Constants.T_VOID) {
+            //corrected concurrent private static field acess
+            wrap(consumed_chars, 1);
+            return BasicType.getType(type);
+        } else if (type == Constants.T_ARRAY) {
+            int dim = 0;
+            do { // Count dimensions
+                dim++;
+            } while (signature.charAt(dim) == '[');
+            // Recurse, but just once, if the signature is ok
+            Type t = getType(signature.substring(dim));
+            //corrected concurrent private static field acess
+            //  consumed_chars += dim; // update counter - is replaced by
+            int _temp = unwrap(consumed_chars) + dim;
+            wrap(consumed_chars, _temp);
+            return new ArrayType(t, dim);
+        } else { // type == T_REFERENCE
+            int index = signature.indexOf(';'); // Look for closing `;'
+            if (index < 0) {
+                throw new ClassFormatException("Invalid signature: " + signature);
+            }
+            //corrected concurrent private static field acess
+            wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed
+            return new ObjectType(signature.substring(1, index).replace('/', '.'));
+        }
+    }
+
+
+    /**
+     * Convert return value of a method (signature) to a Type object.
+     *
+     * @param signature signature string such as (Ljava/lang/String;)V
+     * @return return type
+     */
+    public static Type getReturnType( String signature ) {
+        try {
+            // Read return type after `)'
+            int index = signature.lastIndexOf(')') + 1;
+            return getType(signature.substring(index));
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+    }
+
+
+    /**
+     * Convert arguments of a method (signature) to an array of Type objects.
+     * @param signature signature string such as (Ljava/lang/String;)V
+     * @return array of argument types
+     */
+    public static Type[] getArgumentTypes( String signature ) {
+        List vec = new ArrayList();
+        int index;
+        Type[] types;
+        try { // Read all declarations between for `(' and `)'
+            if (signature.charAt(0) != '(') {
+                throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+            index = 1; // current string position
+            while (signature.charAt(index) != ')') {
+                vec.add(getType(signature.substring(index)));
+                //corrected concurrent private static field acess
+                index += unwrap(consumed_chars); // update position
+            }
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+        types = new Type[vec.size()];
+        vec.toArray(types);
+        return types;
+    }
+
+
+    /** Convert runtime java.lang.Class to BCEL Type object.
+     * @param cl Java class
+     * @return corresponding Type object
+     */
+    public static Type getType( java.lang.Class cl ) {
+        if (cl == null) {
+            throw new IllegalArgumentException("Class must not be null");
+        }
+        /* That's an amzingly easy case, because getName() returns
+         * the signature. That's what we would have liked anyway.
+         */
+        if (cl.isArray()) {
+            return getType(cl.getName());
+        } else if (cl.isPrimitive()) {
+            if (cl == Integer.TYPE) {
+                return INT;
+            } else if (cl == Void.TYPE) {
+                return VOID;
+            } else if (cl == Double.TYPE) {
+                return DOUBLE;
+            } else if (cl == Float.TYPE) {
+                return FLOAT;
+            } else if (cl == Boolean.TYPE) {
+                return BOOLEAN;
+            } else if (cl == Byte.TYPE) {
+                return BYTE;
+            } else if (cl == Short.TYPE) {
+                return SHORT;
+            } else if (cl == Byte.TYPE) {
+                return BYTE;
+            } else if (cl == Long.TYPE) {
+                return LONG;
+            } else if (cl == Character.TYPE) {
+                return CHAR;
+            } else {
+                throw new IllegalStateException("Ooops, what primitive type is " + cl);
+            }
+        } else { // "Real" class
+            return new ObjectType(cl.getName());
+        }
+    }
+
+
+    /**
+     * Convert runtime java.lang.Class[] to BCEL Type objects.
+     * @param classes an array of runtime class objects
+     * @return array of corresponding Type objects
+     */
+    public static Type[] getTypes( java.lang.Class[] classes ) {
+        Type[] ret = new Type[classes.length];
+        for (int i = 0; i < ret.length; i++) {
+            ret[i] = getType(classes[i]);
+        }
+        return ret;
+    }
+
+
+    public static String getSignature( java.lang.reflect.Method meth ) {
+        StringBuffer sb = new StringBuffer("(");
+        Class[] params = meth.getParameterTypes(); // avoid clone
+        for (int j = 0; j < params.length; j++) {
+            sb.append(getType(params[j]).getSignature());
+        }
+        sb.append(")");
+        sb.append(getType(meth.getReturnType()).getSignature());
+        return sb.toString();
+    }
+    
+    private static int size(int coded) {
+       return coded & 3;
+    }
+    
+    private static int consumed(int coded) {
+       return coded >> 2;
+    }
+    
+    private static int encode(int size, int consumed) {
+       return consumed << 2 | size;
+    }
+    
+    static int getArgumentTypesSize( String signature ) {
+        int res = 0;
+        int index;
+        Type[] types;
+        try { // Read all declarations between for `(' and `)'
+            if (signature.charAt(0) != '(') {
+                throw new ClassFormatException("Invalid method signature: " + signature);
+            }
+            index = 1; // current string position
+            while (signature.charAt(index) != ')') {
+                int coded = getTypeSize(signature.substring(index));
+                res += size(coded);
+                index += consumed(coded);
+            }
+        } catch (StringIndexOutOfBoundsException e) { // Should never occur
+            throw new ClassFormatException("Invalid method signature: " + signature, e);
+        }
+        return res;
+    }
+    
+    static final int getTypeSize( String signature ) throws StringIndexOutOfBoundsException {
+        byte type = Utility.typeOfSignature(signature);
+        if (type <= Constants.T_VOID) {
+            return encode(BasicType.getType(type).getSize(), 1);
+        } else if (type == Constants.T_ARRAY) {
+            int dim = 0;
+            do { // Count dimensions
+                dim++;
+            } while (signature.charAt(dim) == '[');
+            // Recurse, but just once, if the signature is ok
+            int consumed = consumed(getTypeSize(signature.substring(dim)));
+            return encode(1, dim + consumed);
+        } else { // type == T_REFERENCE
+            int index = signature.indexOf(';'); // Look for closing `;'
+            if (index < 0) {
+                throw new ClassFormatException("Invalid signature: " + signature);
+            }
+            return encode(1, index + 1);
+        }
+    }
+
+
+       static int getReturnTypeSize(String signature) {
+               int index = signature.lastIndexOf(')') + 1;
+        return getTypeSize(signature.substring(index));
+       }
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/TypedInstruction.java b/java/org/apache/tomcat/util/bcel/generic/TypedInstruction.java
new file mode 100644 (file)
index 0000000..db2b4e9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Get the type associated with an instruction, int for ILOAD, or the type
+ * of the field of a PUTFIELD instruction, e.g..
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface TypedInstruction {
+
+    public Type getType( ConstantPoolGen cpg );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/UnconditionalBranch.java b/java/org/apache/tomcat/util/bcel/generic/UnconditionalBranch.java
new file mode 100644 (file)
index 0000000..710f893
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+
+ * @see GOTO
+ * @see JSR
+ */
+public interface UnconditionalBranch {
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/VariableLengthInstruction.java b/java/org/apache/tomcat/util/bcel/generic/VariableLengthInstruction.java
new file mode 100644 (file)
index 0000000..00704c3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Denotes an instruction to be a variable length instruction, such as
+ * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+
+ * @see GOTO
+ * @see JSR
+ * @see LOOKUPSWITCH
+ * @see TABLESWITCH
+ */
+public interface VariableLengthInstruction {
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/Visitor.java b/java/org/apache/tomcat/util/bcel/generic/Visitor.java
new file mode 100644 (file)
index 0000000..65b4838
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.generic;
+
+/**
+ * Interface implementing the Visitor pattern programming style.
+ * I.e., a class that implements this interface can handle all types of
+ * instructions with the properly typed methods just by calling the accept()
+ * method.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public interface Visitor {
+
+    public void visitStackInstruction( StackInstruction obj );
+
+
+    public void visitLocalVariableInstruction( LocalVariableInstruction obj );
+
+
+    public void visitBranchInstruction( BranchInstruction obj );
+
+
+    public void visitLoadClass( LoadClass obj );
+
+
+    public void visitFieldInstruction( FieldInstruction obj );
+
+
+    public void visitIfInstruction( IfInstruction obj );
+
+
+    public void visitConversionInstruction( ConversionInstruction obj );
+
+
+    public void visitPopInstruction( PopInstruction obj );
+
+
+    public void visitStoreInstruction( StoreInstruction obj );
+
+
+    public void visitTypedInstruction( TypedInstruction obj );
+
+
+    public void visitSelect( Select obj );
+
+
+    public void visitJsrInstruction( JsrInstruction obj );
+
+
+    public void visitGotoInstruction( GotoInstruction obj );
+
+
+    public void visitUnconditionalBranch( UnconditionalBranch obj );
+
+
+    public void visitPushInstruction( PushInstruction obj );
+
+
+    public void visitArithmeticInstruction( ArithmeticInstruction obj );
+
+
+    public void visitCPInstruction( CPInstruction obj );
+
+
+    public void visitInvokeInstruction( InvokeInstruction obj );
+
+
+    public void visitArrayInstruction( ArrayInstruction obj );
+
+
+    public void visitAllocationInstruction( AllocationInstruction obj );
+
+
+    public void visitReturnInstruction( ReturnInstruction obj );
+
+
+    public void visitFieldOrMethod( FieldOrMethod obj );
+
+
+    public void visitConstantPushInstruction( ConstantPushInstruction obj );
+
+
+    public void visitExceptionThrower( ExceptionThrower obj );
+
+
+    public void visitLoadInstruction( LoadInstruction obj );
+
+
+    public void visitVariableLengthInstruction( VariableLengthInstruction obj );
+
+
+    public void visitStackProducer( StackProducer obj );
+
+
+    public void visitStackConsumer( StackConsumer obj );
+
+
+    public void visitACONST_NULL( ACONST_NULL obj );
+
+
+    public void visitGETSTATIC( GETSTATIC obj );
+
+
+    public void visitIF_ICMPLT( IF_ICMPLT obj );
+
+
+    public void visitMONITOREXIT( MONITOREXIT obj );
+
+
+    public void visitIFLT( IFLT obj );
+
+
+    public void visitLSTORE( LSTORE obj );
+
+
+    public void visitPOP2( POP2 obj );
+
+
+    public void visitBASTORE( BASTORE obj );
+
+
+    public void visitISTORE( ISTORE obj );
+
+
+    public void visitCHECKCAST( CHECKCAST obj );
+
+
+    public void visitFCMPG( FCMPG obj );
+
+
+    public void visitI2F( I2F obj );
+
+
+    public void visitATHROW( ATHROW obj );
+
+
+    public void visitDCMPL( DCMPL obj );
+
+
+    public void visitARRAYLENGTH( ARRAYLENGTH obj );
+
+
+    public void visitDUP( DUP obj );
+
+
+    public void visitINVOKESTATIC( INVOKESTATIC obj );
+
+
+    public void visitLCONST( LCONST obj );
+
+
+    public void visitDREM( DREM obj );
+
+
+    public void visitIFGE( IFGE obj );
+
+
+    public void visitCALOAD( CALOAD obj );
+
+
+    public void visitLASTORE( LASTORE obj );
+
+
+    public void visitI2D( I2D obj );
+
+
+    public void visitDADD( DADD obj );
+
+
+    public void visitINVOKESPECIAL( INVOKESPECIAL obj );
+
+
+    public void visitIAND( IAND obj );
+
+
+    public void visitPUTFIELD( PUTFIELD obj );
+
+
+    public void visitILOAD( ILOAD obj );
+
+
+    public void visitDLOAD( DLOAD obj );
+
+
+    public void visitDCONST( DCONST obj );
+
+
+    public void visitNEW( NEW obj );
+
+
+    public void visitIFNULL( IFNULL obj );
+
+
+    public void visitLSUB( LSUB obj );
+
+
+    public void visitL2I( L2I obj );
+
+
+    public void visitISHR( ISHR obj );
+
+
+    public void visitTABLESWITCH( TABLESWITCH obj );
+
+
+    public void visitIINC( IINC obj );
+
+
+    public void visitDRETURN( DRETURN obj );
+
+
+    public void visitFSTORE( FSTORE obj );
+
+
+    public void visitDASTORE( DASTORE obj );
+
+
+    public void visitIALOAD( IALOAD obj );
+
+
+    public void visitDDIV( DDIV obj );
+
+
+    public void visitIF_ICMPGE( IF_ICMPGE obj );
+
+
+    public void visitLAND( LAND obj );
+
+
+    public void visitIDIV( IDIV obj );
+
+
+    public void visitLOR( LOR obj );
+
+
+    public void visitCASTORE( CASTORE obj );
+
+
+    public void visitFREM( FREM obj );
+
+
+    public void visitLDC( LDC obj );
+
+
+    public void visitBIPUSH( BIPUSH obj );
+
+
+    public void visitDSTORE( DSTORE obj );
+
+
+    public void visitF2L( F2L obj );
+
+
+    public void visitFMUL( FMUL obj );
+
+
+    public void visitLLOAD( LLOAD obj );
+
+
+    public void visitJSR( JSR obj );
+
+
+    public void visitFSUB( FSUB obj );
+
+
+    public void visitSASTORE( SASTORE obj );
+
+
+    public void visitALOAD( ALOAD obj );
+
+
+    public void visitDUP2_X2( DUP2_X2 obj );
+
+
+    public void visitRETURN( RETURN obj );
+
+
+    public void visitDALOAD( DALOAD obj );
+
+
+    public void visitSIPUSH( SIPUSH obj );
+
+
+    public void visitDSUB( DSUB obj );
+
+
+    public void visitL2F( L2F obj );
+
+
+    public void visitIF_ICMPGT( IF_ICMPGT obj );
+
+
+    public void visitF2D( F2D obj );
+
+
+    public void visitI2L( I2L obj );
+
+
+    public void visitIF_ACMPNE( IF_ACMPNE obj );
+
+
+    public void visitPOP( POP obj );
+
+
+    public void visitI2S( I2S obj );
+
+
+    public void visitIFEQ( IFEQ obj );
+
+
+    public void visitSWAP( SWAP obj );
+
+
+    public void visitIOR( IOR obj );
+
+
+    public void visitIREM( IREM obj );
+
+
+    public void visitIASTORE( IASTORE obj );
+
+
+    public void visitNEWARRAY( NEWARRAY obj );
+
+
+    public void visitINVOKEINTERFACE( INVOKEINTERFACE obj );
+
+
+    public void visitINEG( INEG obj );
+
+
+    public void visitLCMP( LCMP obj );
+
+
+    public void visitJSR_W( JSR_W obj );
+
+
+    public void visitMULTIANEWARRAY( MULTIANEWARRAY obj );
+
+
+    public void visitDUP_X2( DUP_X2 obj );
+
+
+    public void visitSALOAD( SALOAD obj );
+
+
+    public void visitIFNONNULL( IFNONNULL obj );
+
+
+    public void visitDMUL( DMUL obj );
+
+
+    public void visitIFNE( IFNE obj );
+
+
+    public void visitIF_ICMPLE( IF_ICMPLE obj );
+
+
+    public void visitLDC2_W( LDC2_W obj );
+
+
+    public void visitGETFIELD( GETFIELD obj );
+
+
+    public void visitLADD( LADD obj );
+
+
+    public void visitNOP( NOP obj );
+
+
+    public void visitFALOAD( FALOAD obj );
+
+
+    public void visitINSTANCEOF( INSTANCEOF obj );
+
+
+    public void visitIFLE( IFLE obj );
+
+
+    public void visitLXOR( LXOR obj );
+
+
+    public void visitLRETURN( LRETURN obj );
+
+
+    public void visitFCONST( FCONST obj );
+
+
+    public void visitIUSHR( IUSHR obj );
+
+
+    public void visitBALOAD( BALOAD obj );
+
+
+    public void visitDUP2( DUP2 obj );
+
+
+    public void visitIF_ACMPEQ( IF_ACMPEQ obj );
+
+
+    public void visitIMPDEP1( IMPDEP1 obj );
+
+
+    public void visitMONITORENTER( MONITORENTER obj );
+
+
+    public void visitLSHL( LSHL obj );
+
+
+    public void visitDCMPG( DCMPG obj );
+
+
+    public void visitD2L( D2L obj );
+
+
+    public void visitIMPDEP2( IMPDEP2 obj );
+
+
+    public void visitL2D( L2D obj );
+
+
+    public void visitRET( RET obj );
+
+
+    public void visitIFGT( IFGT obj );
+
+
+    public void visitIXOR( IXOR obj );
+
+
+    public void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj );
+
+
+    public void visitFASTORE( FASTORE obj );
+
+
+    public void visitIRETURN( IRETURN obj );
+
+
+    public void visitIF_ICMPNE( IF_ICMPNE obj );
+
+
+    public void visitFLOAD( FLOAD obj );
+
+
+    public void visitLDIV( LDIV obj );
+
+
+    public void visitPUTSTATIC( PUTSTATIC obj );
+
+
+    public void visitAALOAD( AALOAD obj );
+
+
+    public void visitD2I( D2I obj );
+
+
+    public void visitIF_ICMPEQ( IF_ICMPEQ obj );
+
+
+    public void visitAASTORE( AASTORE obj );
+
+
+    public void visitARETURN( ARETURN obj );
+
+
+    public void visitDUP2_X1( DUP2_X1 obj );
+
+
+    public void visitFNEG( FNEG obj );
+
+
+    public void visitGOTO_W( GOTO_W obj );
+
+
+    public void visitD2F( D2F obj );
+
+
+    public void visitGOTO( GOTO obj );
+
+
+    public void visitISUB( ISUB obj );
+
+
+    public void visitF2I( F2I obj );
+
+
+    public void visitDNEG( DNEG obj );
+
+
+    public void visitICONST( ICONST obj );
+
+
+    public void visitFDIV( FDIV obj );
+
+
+    public void visitI2B( I2B obj );
+
+
+    public void visitLNEG( LNEG obj );
+
+
+    public void visitLREM( LREM obj );
+
+
+    public void visitIMUL( IMUL obj );
+
+
+    public void visitIADD( IADD obj );
+
+
+    public void visitLSHR( LSHR obj );
+
+
+    public void visitLOOKUPSWITCH( LOOKUPSWITCH obj );
+
+
+    public void visitDUP_X1( DUP_X1 obj );
+
+
+    public void visitFCMPL( FCMPL obj );
+
+
+    public void visitI2C( I2C obj );
+
+
+    public void visitLMUL( LMUL obj );
+
+
+    public void visitLUSHR( LUSHR obj );
+
+
+    public void visitISHL( ISHL obj );
+
+
+    public void visitLALOAD( LALOAD obj );
+
+
+    public void visitASTORE( ASTORE obj );
+
+
+    public void visitANEWARRAY( ANEWARRAY obj );
+
+
+    public void visitFRETURN( FRETURN obj );
+
+
+    public void visitFADD( FADD obj );
+
+
+    public void visitBREAKPOINT( BREAKPOINT obj );
+}
diff --git a/java/org/apache/tomcat/util/bcel/generic/package.html b/java/org/apache/tomcat/util/bcel/generic/package.html
new file mode 100644 (file)
index 0000000..2ae2126
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+$Id$
+-->
+</head>
+<body bgcolor="white">
+<p>
+This package contains the "generic" part of the
+<a href="http://jakarta.apache.org/bcel/">Byte Code Engineering
+Library</a>, i.e., classes to dynamically modify class objects and
+byte code instructions.
+</p>
+</body>
+</html>
diff --git a/java/org/apache/tomcat/util/bcel/package.html b/java/org/apache/tomcat/util/bcel/package.html
new file mode 100644 (file)
index 0000000..773bac1
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+$Id$
+-->
+</head>
+<body bgcolor="white">
+<p>
+This package contains basic classes for the
+<a href="http://jakarta.apache.org/bcel/">Byte Code Engineering Library</a>
+ and constants defined by the
+<a href="http://java.sun.com/docs/books/vmspec/html/VMSpecTOC.doc.html">
+ JVM specification</a>.
+</p>
+</body>
+</html>
diff --git a/java/org/apache/tomcat/util/bcel/util/AttributeHTML.java b/java/org/apache/tomcat/util/bcel/util/AttributeHTML.java
new file mode 100644 (file)
index 0000000..52c2f54
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Code;
+import org.apache.tomcat.util.bcel.classfile.CodeException;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.ConstantValue;
+import org.apache.tomcat.util.bcel.classfile.ExceptionTable;
+import org.apache.tomcat.util.bcel.classfile.InnerClass;
+import org.apache.tomcat.util.bcel.classfile.InnerClasses;
+import org.apache.tomcat.util.bcel.classfile.LineNumber;
+import org.apache.tomcat.util.bcel.classfile.LineNumberTable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariableTable;
+import org.apache.tomcat.util.bcel.classfile.SourceFile;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Convert found attributes into HTML file.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * 
+ */
+final class AttributeHTML implements org.apache.tomcat.util.bcel.Constants {
+
+    private String class_name; // name of current class
+    private PrintWriter file; // file to write to
+    private int attr_count = 0;
+    private ConstantHTML constant_html;
+    private ConstantPool constant_pool;
+
+
+    AttributeHTML(String dir, String class_name, ConstantPool constant_pool,
+            ConstantHTML constant_html) throws IOException {
+        this.class_name = class_name;
+        this.constant_pool = constant_pool;
+        this.constant_html = constant_html;
+        file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html"));
+        file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>");
+    }
+
+
+    private final String codeLink( int link, int method_number ) {
+        return "<A HREF=\"" + class_name + "_code.html#code" + method_number + "@" + link
+                + "\" TARGET=Code>" + link + "</A>";
+    }
+
+
+    final void close() {
+        file.println("</TABLE></BODY></HTML>");
+        file.close();
+    }
+
+
+    final void writeAttribute( Attribute attribute, String anchor ) throws IOException {
+        writeAttribute(attribute, anchor, 0);
+    }
+
+
+    final void writeAttribute( Attribute attribute, String anchor, int method_number )
+            throws IOException {
+        byte tag = attribute.getTag();
+        int index;
+        if (tag == ATTR_UNKNOWN) {
+            return;
+        }
+        attr_count++; // Increment number of attributes found so far
+        if (attr_count % 2 == 0) {
+            file.print("<TR BGCOLOR=\"#C0C0C0\"><TD>");
+        } else {
+            file.print("<TR BGCOLOR=\"#A0A0A0\"><TD>");
+        }
+        file.println("<H4><A NAME=\"" + anchor + "\">" + attr_count + " " + ATTRIBUTE_NAMES[tag]
+                + "</A></H4>");
+        /* Handle different attributes
+         */
+        switch (tag) {
+            case ATTR_CODE:
+                Code c = (Code) attribute;
+                // Some directly printable values
+                file.print("<UL><LI>Maximum stack size = " + c.getMaxStack()
+                        + "</LI>\n<LI>Number of local variables = " + c.getMaxLocals()
+                        + "</LI>\n<LI><A HREF=\"" + class_name + "_code.html#method"
+                        + method_number + "\" TARGET=Code>Byte code</A></LI></UL>\n");
+                // Get handled exceptions and list them
+                CodeException[] ce = c.getExceptionTable();
+                int len = ce.length;
+                if (len > 0) {
+                    file.print("<P><B>Exceptions handled</B><UL>");
+                    for (int i = 0; i < len; i++) {
+                        int catch_type = ce[i].getCatchType(); // Index in constant pool
+                        file.print("<LI>");
+                        if (catch_type != 0) {
+                            file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html
+                        } else {
+                            file.print("Any Exception");
+                        }
+                        file.print("<BR>(Ranging from lines "
+                                + codeLink(ce[i].getStartPC(), method_number) + " to "
+                                + codeLink(ce[i].getEndPC(), method_number) + ", handled at line "
+                                + codeLink(ce[i].getHandlerPC(), method_number) + ")</LI>");
+                    }
+                    file.print("</UL>");
+                }
+                break;
+            case ATTR_CONSTANT_VALUE:
+                index = ((ConstantValue) attribute).getConstantValueIndex();
+                // Reference _cp.html
+                file.print("<UL><LI><A HREF=\"" + class_name + "_cp.html#cp" + index
+                        + "\" TARGET=\"ConstantPool\">Constant value index(" + index
+                        + ")</A></UL>\n");
+                break;
+            case ATTR_SOURCE_FILE:
+                index = ((SourceFile) attribute).getSourceFileIndex();
+                // Reference _cp.html
+                file.print("<UL><LI><A HREF=\"" + class_name + "_cp.html#cp" + index
+                        + "\" TARGET=\"ConstantPool\">Source file index(" + index + ")</A></UL>\n");
+                break;
+            case ATTR_EXCEPTIONS:
+                // List thrown exceptions
+                int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable();
+                file.print("<UL>");
+                for (int i = 0; i < indices.length; i++) {
+                    file.print("<LI><A HREF=\"" + class_name + "_cp.html#cp" + indices[i]
+                            + "\" TARGET=\"ConstantPool\">Exception class index(" + indices[i]
+                            + ")</A>\n");
+                }
+                file.print("</UL>\n");
+                break;
+            case ATTR_LINE_NUMBER_TABLE:
+                LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable();
+                // List line number pairs
+                file.print("<P>");
+                for (int i = 0; i < line_numbers.length; i++) {
+                    file.print("(" + line_numbers[i].getStartPC() + ",&nbsp;"
+                            + line_numbers[i].getLineNumber() + ")");
+                    if (i < line_numbers.length - 1) {
+                        file.print(", "); // breakable
+                    }
+                }
+                break;
+            case ATTR_LOCAL_VARIABLE_TABLE:
+                LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable();
+                // List name, range and type
+                file.print("<UL>");
+                for (int i = 0; i < vars.length; i++) {
+                    index = vars[i].getSignatureIndex();
+                    String signature = ((ConstantUtf8) constant_pool.getConstant(index,
+                            CONSTANT_Utf8)).getBytes();
+                    signature = Utility.signatureToString(signature, false);
+                    int start = vars[i].getStartPC();
+                    int end = (start + vars[i].getLength());
+                    file.println("<LI>" + Class2HTML.referenceType(signature) + "&nbsp;<B>"
+                            + vars[i].getName() + "</B> in slot %" + vars[i].getIndex()
+                            + "<BR>Valid from lines " + "<A HREF=\"" + class_name
+                            + "_code.html#code" + method_number + "@" + start + "\" TARGET=Code>"
+                            + start + "</A> to " + "<A HREF=\"" + class_name + "_code.html#code"
+                            + method_number + "@" + end + "\" TARGET=Code>" + end + "</A></LI>");
+                }
+                file.print("</UL>\n");
+                break;
+            case ATTR_INNER_CLASSES:
+                InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses();
+                // List inner classes
+                file.print("<UL>");
+                for (int i = 0; i < classes.length; i++) {
+                    String name, access;
+                    index = classes[i].getInnerNameIndex();
+                    if (index > 0) {
+                        name = ((ConstantUtf8) constant_pool.getConstant(index, CONSTANT_Utf8))
+                                .getBytes();
+                    } else {
+                        name = "&lt;anonymous&gt;";
+                    }
+                    access = Utility.accessToString(classes[i].getInnerAccessFlags());
+                    file.print("<LI><FONT COLOR=\"#FF0000\">" + access + "</FONT> "
+                            + constant_html.referenceConstant(classes[i].getInnerClassIndex())
+                            + " in&nbsp;class "
+                            + constant_html.referenceConstant(classes[i].getOuterClassIndex())
+                            + " named " + name + "</LI>\n");
+                }
+                file.print("</UL>\n");
+                break;
+            default: // Such as Unknown attribute or Deprecated
+                file.print("<P>" + attribute.toString());
+        }
+        file.println("</TD></TR>");
+        file.flush();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/BCELComparator.java b/java/org/apache/tomcat/util/bcel/util/BCELComparator.java
new file mode 100644 (file)
index 0000000..866fa2b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+/**
+ * Used for BCEL comparison strategy
+ * 
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @version $Id$
+ * @since 5.2
+ */
+public interface BCELComparator {
+
+    /**
+     * Compare two objects and return what THIS.equals(THAT) should return
+     * 
+     * @param THIS
+     * @param THAT
+     * @return true if and only if THIS equals THAT
+     */
+    public boolean equals( Object THIS, Object THAT );
+
+
+    /**
+     * Return hashcode for THIS.hashCode()
+     * 
+     * @param THIS
+     * @return hashcode for THIS.hashCode()
+     */
+    public int hashCode( Object THIS );
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/BCELFactory.java b/java/org/apache/tomcat/util/bcel/util/BCELFactory.java
new file mode 100644 (file)
index 0000000..0cdd27a
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+import org.apache.tomcat.util.bcel.generic.AllocationInstruction;
+import org.apache.tomcat.util.bcel.generic.ArrayInstruction;
+import org.apache.tomcat.util.bcel.generic.ArrayType;
+import org.apache.tomcat.util.bcel.generic.BranchHandle;
+import org.apache.tomcat.util.bcel.generic.BranchInstruction;
+import org.apache.tomcat.util.bcel.generic.CHECKCAST;
+import org.apache.tomcat.util.bcel.generic.CPInstruction;
+import org.apache.tomcat.util.bcel.generic.CodeExceptionGen;
+import org.apache.tomcat.util.bcel.generic.ConstantPoolGen;
+import org.apache.tomcat.util.bcel.generic.ConstantPushInstruction;
+import org.apache.tomcat.util.bcel.generic.EmptyVisitor;
+import org.apache.tomcat.util.bcel.generic.FieldInstruction;
+import org.apache.tomcat.util.bcel.generic.IINC;
+import org.apache.tomcat.util.bcel.generic.INSTANCEOF;
+import org.apache.tomcat.util.bcel.generic.Instruction;
+import org.apache.tomcat.util.bcel.generic.InstructionConstants;
+import org.apache.tomcat.util.bcel.generic.InstructionHandle;
+import org.apache.tomcat.util.bcel.generic.InvokeInstruction;
+import org.apache.tomcat.util.bcel.generic.LDC;
+import org.apache.tomcat.util.bcel.generic.LDC2_W;
+import org.apache.tomcat.util.bcel.generic.LocalVariableInstruction;
+import org.apache.tomcat.util.bcel.generic.MULTIANEWARRAY;
+import org.apache.tomcat.util.bcel.generic.MethodGen;
+import org.apache.tomcat.util.bcel.generic.NEWARRAY;
+import org.apache.tomcat.util.bcel.generic.ObjectType;
+import org.apache.tomcat.util.bcel.generic.RET;
+import org.apache.tomcat.util.bcel.generic.ReturnInstruction;
+import org.apache.tomcat.util.bcel.generic.Select;
+import org.apache.tomcat.util.bcel.generic.Type;
+
+/**
+ * Factory creates il.append() statements, and sets instruction targets.
+ * A helper class for BCELifier.
+ *
+ * @see BCELifier
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+class BCELFactory extends EmptyVisitor {
+
+    private MethodGen _mg;
+    private PrintWriter _out;
+    private ConstantPoolGen _cp;
+
+
+    BCELFactory(MethodGen mg, PrintWriter out) {
+        _mg = mg;
+        _cp = mg.getConstantPool();
+        _out = out;
+    }
+
+    private Map branch_map = new HashMap(); // Map<Instruction, InstructionHandle>
+
+
+    public void start() {
+        if (!_mg.isAbstract() && !_mg.isNative()) {
+            for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih
+                    .getNext()) {
+                Instruction i = ih.getInstruction();
+                if (i instanceof BranchInstruction) {
+                    branch_map.put(i, ih); // memorize container
+                }
+                if (ih.hasTargeters()) {
+                    if (i instanceof BranchInstruction) {
+                        _out.println("    InstructionHandle ih_" + ih.getPosition() + ";");
+                    } else {
+                        _out.print("    InstructionHandle ih_" + ih.getPosition() + " = ");
+                    }
+                } else {
+                    _out.print("    ");
+                }
+                if (!visitInstruction(i)) {
+                    i.accept(this);
+                }
+            }
+            updateBranchTargets();
+            updateExceptionHandlers();
+        }
+    }
+
+
+    private boolean visitInstruction( Instruction i ) {
+        short opcode = i.getOpcode();
+        if ((InstructionConstants.INSTRUCTIONS[opcode] != null)
+                && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below
+            _out.println("il.append(InstructionConstants."
+                    + i.getName().toUpperCase(Locale.ENGLISH) + ");");
+            return true;
+        }
+        return false;
+    }
+
+
+    public void visitLocalVariableInstruction( LocalVariableInstruction i ) {
+        short opcode = i.getOpcode();
+        Type type = i.getType(_cp);
+        if (opcode == Constants.IINC) {
+            _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement()
+                    + "));");
+        } else {
+            String kind = (opcode < Constants.ISTORE) ? "Load" : "Store";
+            _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type)
+                    + ", " + i.getIndex() + "));");
+        }
+    }
+
+
+    public void visitArrayInstruction( ArrayInstruction i ) {
+        short opcode = i.getOpcode();
+        Type type = i.getType(_cp);
+        String kind = (opcode < Constants.IASTORE) ? "Load" : "Store";
+        _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type)
+                + "));");
+    }
+
+
+    public void visitFieldInstruction( FieldInstruction i ) {
+        short opcode = i.getOpcode();
+        String class_name = i.getClassName(_cp);
+        String field_name = i.getFieldName(_cp);
+        Type type = i.getFieldType(_cp);
+        _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name
+                + "\", " + BCELifier.printType(type) + ", " + "Constants."
+                + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));");
+    }
+
+
+    public void visitInvokeInstruction( InvokeInstruction i ) {
+        short opcode = i.getOpcode();
+        String class_name = i.getClassName(_cp);
+        String method_name = i.getMethodName(_cp);
+        Type type = i.getReturnType(_cp);
+        Type[] arg_types = i.getArgumentTypes(_cp);
+        _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name
+                + "\", " + BCELifier.printType(type) + ", "
+                + BCELifier.printArgumentTypes(arg_types) + ", " + "Constants."
+                + Constants.OPCODE_NAMES[opcode].toUpperCase(Locale.ENGLISH) + "));");
+    }
+
+
+    public void visitAllocationInstruction( AllocationInstruction i ) {
+        Type type;
+        if (i instanceof CPInstruction) {
+            type = ((CPInstruction) i).getType(_cp);
+        } else {
+            type = ((NEWARRAY) i).getType();
+        }
+        short opcode = ((Instruction) i).getOpcode();
+        int dim = 1;
+        switch (opcode) {
+            case Constants.NEW:
+                _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName()
+                        + "\"));");
+                break;
+            case Constants.MULTIANEWARRAY:
+                dim = ((MULTIANEWARRAY) i).getDimensions();
+                /* FALL THRU */
+            case Constants.ANEWARRAY:
+            case Constants.NEWARRAY:
+                if (type instanceof ArrayType) {
+                    type = ((ArrayType) type).getBasicType();
+                }
+                _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type)
+                        + ", (short) " + dim + "));");
+                break;
+            default:
+                throw new RuntimeException("Oops: " + opcode);
+        }
+    }
+
+
+    private void createConstant( Object value ) {
+        String embed = value.toString();
+        if (value instanceof String) {
+            embed = '"' + Utility.convertString(embed) + '"';
+        } else if (value instanceof Character) {
+            embed = "(char)0x" + Integer.toHexString(((Character) value).charValue());
+        } else if (value instanceof Float) {
+            embed += "f";
+        } else if (value instanceof Long) {
+            embed += "L";
+        }
+        _out.println("il.append(new PUSH(_cp, " + embed + "));");
+    }
+
+
+    public void visitLDC( LDC i ) {
+        createConstant(i.getValue(_cp));
+    }
+
+
+    public void visitLDC2_W( LDC2_W i ) {
+        createConstant(i.getValue(_cp));
+    }
+
+
+    public void visitConstantPushInstruction( ConstantPushInstruction i ) {
+        createConstant(i.getValue());
+    }
+
+
+    public void visitINSTANCEOF( INSTANCEOF i ) {
+        Type type = i.getType(_cp);
+        _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));");
+    }
+
+
+    public void visitCHECKCAST( CHECKCAST i ) {
+        Type type = i.getType(_cp);
+        _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));");
+    }
+
+
+    public void visitReturnInstruction( ReturnInstruction i ) {
+        Type type = i.getType(_cp);
+        _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));");
+    }
+
+    // Memorize BranchInstructions that need an update
+    private List branches = new ArrayList();
+
+
+    public void visitBranchInstruction( BranchInstruction bi ) {
+        BranchHandle bh = (BranchHandle) branch_map.get(bi);
+        int pos = bh.getPosition();
+        String name = bi.getName() + "_" + pos;
+        if (bi instanceof Select) {
+            Select s = (Select) bi;
+            branches.add(bi);
+            StringBuffer args = new StringBuffer("new int[] { ");
+            int[] matchs = s.getMatchs();
+            for (int i = 0; i < matchs.length; i++) {
+                args.append(matchs[i]);
+                if (i < matchs.length - 1) {
+                    args.append(", ");
+                }
+            }
+            args.append(" }");
+            _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH)
+                    + "(" + args + ", new InstructionHandle[] { ");
+            for (int i = 0; i < matchs.length; i++) {
+                _out.print("null");
+                if (i < matchs.length - 1) {
+                    _out.print(", ");
+                }
+            }
+            _out.println(" }, null);");
+        } else {
+            int t_pos = bh.getTarget().getPosition();
+            String target;
+            if (pos > t_pos) {
+                target = "ih_" + t_pos;
+            } else {
+                branches.add(bi);
+                target = "null";
+            }
+            _out.println("    BranchInstruction " + name + " = _factory.createBranchInstruction("
+                    + "Constants." + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target
+                    + ");");
+        }
+        if (bh.hasTargeters()) {
+            _out.println("    ih_" + pos + " = il.append(" + name + ");");
+        } else {
+            _out.println("    il.append(" + name + ");");
+        }
+    }
+
+
+    public void visitRET( RET i ) {
+        _out.println("il.append(new RET(" + i.getIndex() + ")));");
+    }
+
+
+    private void updateBranchTargets() {
+        for (Iterator i = branches.iterator(); i.hasNext();) {
+            BranchInstruction bi = (BranchInstruction) i.next();
+            BranchHandle bh = (BranchHandle) branch_map.get(bi);
+            int pos = bh.getPosition();
+            String name = bi.getName() + "_" + pos;
+            int t_pos = bh.getTarget().getPosition();
+            _out.println("    " + name + ".setTarget(ih_" + t_pos + ");");
+            if (bi instanceof Select) {
+                InstructionHandle[] ihs = ((Select) bi).getTargets();
+                for (int j = 0; j < ihs.length; j++) {
+                    t_pos = ihs[j].getPosition();
+                    _out.println("    " + name + ".setTarget(" + j + ", ih_" + t_pos + ");");
+                }
+            }
+        }
+    }
+
+
+    private void updateExceptionHandlers() {
+        CodeExceptionGen[] handlers = _mg.getExceptionHandlers();
+        for (int i = 0; i < handlers.length; i++) {
+            CodeExceptionGen h = handlers[i];
+            String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h
+                    .getCatchType());
+            _out.println("    method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition()
+                    + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_"
+                    + h.getHandlerPC().getPosition() + ", " + type + ");");
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/BCELifier.java b/java/org/apache/tomcat/util/bcel/util/BCELifier.java
new file mode 100644 (file)
index 0000000..4acc55b
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Locale;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.Repository;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.ConstantValue;
+import org.apache.tomcat.util.bcel.classfile.Field;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+import org.apache.tomcat.util.bcel.generic.ArrayType;
+import org.apache.tomcat.util.bcel.generic.ConstantPoolGen;
+import org.apache.tomcat.util.bcel.generic.MethodGen;
+import org.apache.tomcat.util.bcel.generic.Type;
+
+/** 
+ * This class takes a given JavaClass object and converts it to a
+ * Java program that creates that very class using BCEL. This
+ * gives new users of BCEL a useful example showing how things
+ * are done with BCEL. It does not cover all features of BCEL,
+ * but tries to mimic hand-written code as close as possible.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ */
+public class BCELifier extends org.apache.tomcat.util.bcel.classfile.EmptyVisitor {
+
+    private static final int FLAG_FOR_UNKNOWN = -1;
+    private static final int FLAG_FOR_CLASS = 0;
+    private static final int FLAG_FOR_METHOD = 1;
+    private JavaClass _clazz;
+    private PrintWriter _out;
+    private ConstantPoolGen _cp;
+
+
+    /** @param clazz Java class to "decompile"
+     * @param out where to output Java program
+     */
+    public BCELifier(JavaClass clazz, OutputStream out) {
+        _clazz = clazz;
+        _out = new PrintWriter(out);
+        _cp = new ConstantPoolGen(_clazz.getConstantPool());
+    }
+
+
+    /** Start Java code generation
+     */
+    public void start() {
+        visitJavaClass(_clazz);
+        _out.flush();
+    }
+
+
+    public void visitJavaClass( JavaClass clazz ) {
+        String class_name = clazz.getClassName();
+        String super_name = clazz.getSuperclassName();
+        String package_name = clazz.getPackageName();
+        String inter = Utility.printArray(clazz.getInterfaceNames(), false, true);
+        if (!"".equals(package_name)) {
+            class_name = class_name.substring(package_name.length() + 1);
+            _out.println("package " + package_name + ";");
+            _out.println();
+        }
+        _out.println("import org.apache.tomcat.util.bcel.generic.*;");
+        _out.println("import org.apache.tomcat.util.bcel.classfile.*;");
+        _out.println("import org.apache.tomcat.util.bcel.*;");
+        _out.println("import java.io.*;");
+        _out.println();
+        _out.println("public class " + class_name + "Creator implements Constants {");
+        _out.println("  private InstructionFactory _factory;");
+        _out.println("  private ConstantPoolGen    _cp;");
+        _out.println("  private ClassGen           _cg;");
+        _out.println();
+        _out.println("  public " + class_name + "Creator() {");
+        _out.println("    _cg = new ClassGen(\""
+                + (("".equals(package_name)) ? class_name : package_name + "." + class_name)
+                + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", "
+                + printFlags(clazz.getAccessFlags(), FLAG_FOR_CLASS) + ", " + "new String[] { "
+                + inter + " });");
+        _out.println();
+        _out.println("    _cp = _cg.getConstantPool();");
+        _out.println("    _factory = new InstructionFactory(_cg, _cp);");
+        _out.println("  }");
+        _out.println();
+        printCreate();
+        Field[] fields = clazz.getFields();
+        if (fields.length > 0) {
+            _out.println("  private void createFields() {");
+            _out.println("    FieldGen field;");
+            for (int i = 0; i < fields.length; i++) {
+                fields[i].accept(this);
+            }
+            _out.println("  }");
+            _out.println();
+        }
+        Method[] methods = clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            _out.println("  private void createMethod_" + i + "() {");
+            methods[i].accept(this);
+            _out.println("  }");
+            _out.println();
+        }
+        printMain();
+        _out.println("}");
+    }
+
+
+    private void printCreate() {
+        _out.println("  public void create(OutputStream out) throws IOException {");
+        Field[] fields = _clazz.getFields();
+        if (fields.length > 0) {
+            _out.println("    createFields();");
+        }
+        Method[] methods = _clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            _out.println("    createMethod_" + i + "();");
+        }
+        _out.println("    _cg.getJavaClass().dump(out);");
+        _out.println("  }");
+        _out.println();
+    }
+
+
+    private void printMain() {
+        String class_name = _clazz.getClassName();
+        _out.println("  public static void main(String[] args) throws Exception {");
+        _out.println("    " + class_name + "Creator creator = new " + class_name + "Creator();");
+        _out.println("    creator.create(new FileOutputStream(\"" + class_name + ".class\"));");
+        _out.println("  }");
+    }
+
+
+    public void visitField( Field field ) {
+        _out.println();
+        _out.println("    field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", "
+                + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);");
+        ConstantValue cv = field.getConstantValue();
+        if (cv != null) {
+            String value = cv.toString();
+            _out.println("    field.setInitValue(" + value + ")");
+        }
+        _out.println("    _cg.addField(field.getField());");
+    }
+
+
+    public void visitMethod( Method method ) {
+        MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp);
+        Type result_type = mg.getReturnType();
+        Type[] arg_types = mg.getArgumentTypes();
+        _out.println("    InstructionList il = new InstructionList();");
+        _out.println("    MethodGen method = new MethodGen("
+                + printFlags(method.getAccessFlags(), FLAG_FOR_METHOD) + ", "
+                + printType(result_type) + ", " + printArgumentTypes(arg_types) + ", "
+                + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true)
+                + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);");
+        _out.println();
+        BCELFactory factory = new BCELFactory(mg, _out);
+        factory.start();
+        _out.println("    method.setMaxStack();");
+        _out.println("    method.setMaxLocals();");
+        _out.println("    _cg.addMethod(method.getMethod());");
+        _out.println("    il.dispose();");
+    }
+
+
+    static String printFlags( int flags ) {
+        return printFlags(flags, FLAG_FOR_UNKNOWN);
+    }
+
+
+    static String printFlags( int flags, int reason ) {
+        if (flags == 0) {
+            return "0";
+        }
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0, pow = 1; pow <= Constants.MAX_ACC_FLAG; i++) {
+            if ((flags & pow) != 0) {
+                if ((pow == Constants.ACC_SYNCHRONIZED) && (reason == FLAG_FOR_CLASS)) {
+                    buf.append("ACC_SUPER | ");
+                } else if ((pow == Constants.ACC_VOLATILE) && (reason == FLAG_FOR_METHOD)) {
+                    buf.append("ACC_BRIDGE | ");
+                } else if ((pow == Constants.ACC_TRANSIENT) && (reason == FLAG_FOR_METHOD)) {
+                    buf.append("ACC_VARARGS | ");
+                } else {
+                    buf.append("ACC_")
+                            .append(Constants.ACCESS_NAMES[i].toUpperCase(Locale.ENGLISH)).append(
+                                    " | ");
+                }
+            }
+            pow <<= 1;
+        }
+        String str = buf.toString();
+        return str.substring(0, str.length() - 3);
+    }
+
+
+    static String printArgumentTypes( Type[] arg_types ) {
+        if (arg_types.length == 0) {
+            return "Type.NO_ARGS";
+        }
+        StringBuffer args = new StringBuffer();
+        for (int i = 0; i < arg_types.length; i++) {
+            args.append(printType(arg_types[i]));
+            if (i < arg_types.length - 1) {
+                args.append(", ");
+            }
+        }
+        return "new Type[] { " + args.toString() + " }";
+    }
+
+
+    static String printType( Type type ) {
+        return printType(type.getSignature());
+    }
+
+
+    static String printType( String signature ) {
+        Type type = Type.getType(signature);
+        byte t = type.getType();
+        if (t <= Constants.T_VOID) {
+            return "Type." + Constants.TYPE_NAMES[t].toUpperCase(Locale.ENGLISH);
+        } else if (type.toString().equals("java.lang.String")) {
+            return "Type.STRING";
+        } else if (type.toString().equals("java.lang.Object")) {
+            return "Type.OBJECT";
+        } else if (type.toString().equals("java.lang.StringBuffer")) {
+            return "Type.STRINGBUFFER";
+        } else if (type instanceof ArrayType) {
+            ArrayType at = (ArrayType) type;
+            return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions()
+                    + ")";
+        } else {
+            return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")";
+        }
+    }
+
+
+    /** Default main method
+     */
+    public static void main( String[] argv ) throws Exception {
+        JavaClass java_class;
+        String name = argv[0];
+        if ((java_class = Repository.lookupClass(name)) == null) {
+            java_class = new ClassParser(name).parse(); // May throw IOException
+        }
+        BCELifier bcelifier = new BCELifier(java_class, System.out);
+        bcelifier.start();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ByteSequence.java b/java/org/apache/tomcat/util/bcel/util/ByteSequence.java
new file mode 100644 (file)
index 0000000..9823df5
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+
+/**
+ * Utility class that implements a sequence of bytes which can be read
+ * via the `readByte()' method. This is used to implement a wrapper for the 
+ * Java byte code stream to gain some more readability.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public final class ByteSequence extends DataInputStream {
+
+    private ByteArrayStream byte_stream;
+
+
+    public ByteSequence(byte[] bytes) {
+        super(new ByteArrayStream(bytes));
+        byte_stream = (ByteArrayStream) in;
+    }
+
+
+    public final int getIndex() {
+        return byte_stream.getPosition();
+    }
+
+
+    final void unreadByte() {
+        byte_stream.unreadByte();
+    }
+
+    private static final class ByteArrayStream extends ByteArrayInputStream {
+
+        ByteArrayStream(byte[] bytes) {
+            super(bytes);
+        }
+
+
+        final int getPosition() {
+            return pos;
+        } // is protected in ByteArrayInputStream
+
+
+        final void unreadByte() {
+            if (pos > 0) {
+                pos--;
+            }
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/Class2HTML.java b/java/org/apache/tomcat/util/bcel/util/Class2HTML.java
new file mode 100644 (file)
index 0000000..0328609
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Read class file(s) and convert them into HTML files.
+ *
+ * Given a JavaClass object "class" that is in package "package" five files
+ * will be created in the specified directory.
+ *
+ * <OL>
+ * <LI> "package"."class".html as the main file which defines the frames for
+ * the following subfiles.
+ * <LI>  "package"."class"_attributes.html contains all (known) attributes found in the file
+ * <LI>  "package"."class"_cp.html contains the constant pool
+ * <LI>  "package"."class"_code.html contains the byte code
+ * <LI>  "package"."class"_methods.html contains references to all methods and fields of the class
+ * </OL>
+ *
+ * All subfiles reference each other appropiately, e.g. clicking on a
+ * method in the Method's frame will jump to the appropiate method in
+ * the Code frame.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ */
+public class Class2HTML implements Constants {
+
+    private JavaClass java_class; // current class object
+    private String dir;
+    private static String class_package; // name of package, unclean to make it static, but ...
+    private static String class_name; // name of current class, dito
+    private static ConstantPool constant_pool;
+
+
+    /**
+     * Write contents of the given JavaClass into HTML files.
+     * 
+     * @param java_class The class to write
+     * @param dir The directory to put the files in
+     */
+    public Class2HTML(JavaClass java_class, String dir) throws IOException {
+        Method[] methods = java_class.getMethods();
+        this.java_class = java_class;
+        this.dir = dir;
+        class_name = java_class.getClassName(); // Remember full name
+        constant_pool = java_class.getConstantPool();
+        // Get package name by tacking off everything after the last `.'
+        int index = class_name.lastIndexOf('.');
+        if (index > -1) {
+            class_package = class_name.substring(0, index);
+        } else {
+            class_package = ""; // default package
+        }
+        ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods,
+                constant_pool);
+        /* Attributes can't be written in one step, so we just open a file
+         * which will be written consequently.
+         */
+        AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool,
+                constant_html);
+//        MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(),
+//                constant_html, attribute_html);
+        // Write main file (with frames, yuk)
+        writeMainHTML(attribute_html);
+        new CodeHTML(dir, class_name, methods, constant_pool, constant_html);
+        attribute_html.close();
+    }
+
+
+    public static void main( String argv[] ) {
+        String[] file_name = new String[argv.length];
+        int files = 0;
+        ClassParser parser = null;
+        JavaClass java_class = null;
+        String zip_file = null;
+        char sep = System.getProperty("file.separator").toCharArray()[0];
+        String dir = "." + sep; // Where to store HTML files
+        try {
+            /* Parse command line arguments.
+             */
+            for (int i = 0; i < argv.length; i++) {
+                if (argv[i].charAt(0) == '-') { // command line switch
+                    if (argv[i].equals("-d")) { // Specify target directory, default `.�
+                        dir = argv[++i];
+                        if (!dir.endsWith("" + sep)) {
+                            dir = dir + sep;
+                        }
+                        new File(dir).mkdirs(); // Create target directory if necessary
+                    } else if (argv[i].equals("-zip")) {
+                        zip_file = argv[++i];
+                    } else {
+                        System.out.println("Unknown option " + argv[i]);
+                    }
+                } else {
+                    file_name[files++] = argv[i];
+                }
+            }
+            if (files == 0) {
+                System.err.println("Class2HTML: No input files specified.");
+            } else { // Loop through files ...
+                for (int i = 0; i < files; i++) {
+                    System.out.print("Processing " + file_name[i] + "...");
+                    if (zip_file == null) {
+                        parser = new ClassParser(file_name[i]); // Create parser object from file
+                    } else {
+                        parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file
+                    }
+                    java_class = parser.parse();
+                    new Class2HTML(java_class, dir);
+                    System.out.println("Done.");
+                }
+            }
+        } catch (Exception e) {
+            System.out.println(e);
+            e.printStackTrace(System.out);
+        }
+    }
+
+
+    /**
+     * Utility method that converts a class reference in the constant pool,
+     * i.e., an index to a string.
+     */
+    static String referenceClass( int index ) {
+        String str = constant_pool.getConstantString(index, CONSTANT_Class);
+        str = Utility.compactClassName(str);
+        str = Utility.compactClassName(str, class_package + ".", true);
+        return "<A HREF=\"" + class_name + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + str
+                + "</A>";
+    }
+
+
+    static final String referenceType( String type ) {
+        String short_type = Utility.compactClassName(type);
+        short_type = Utility.compactClassName(short_type, class_package + ".", true);
+        int index = type.indexOf('['); // Type is an array?
+        String base_type = type;
+        if (index > -1) {
+            base_type = type.substring(0, index); // Tack of the `['           
+        }
+        // test for basic type
+        if (base_type.equals("int") || base_type.equals("short") || base_type.equals("boolean")
+                || base_type.equals("void") || base_type.equals("char") || base_type.equals("byte")
+                || base_type.equals("long") || base_type.equals("double")
+                || base_type.equals("float")) {
+            return "<FONT COLOR=\"#00FF00\">" + type + "</FONT>";
+        } else {
+            return "<A HREF=\"" + base_type + ".html\" TARGET=_top>" + short_type + "</A>";
+        }
+    }
+
+
+    static String toHTML( String str ) {
+        StringBuffer buf = new StringBuffer();
+        try { // Filter any characters HTML doesn't like such as < and > in particular
+            for (int i = 0; i < str.length(); i++) {
+                char ch;
+                switch (ch = str.charAt(i)) {
+                    case '<':
+                        buf.append("&lt;");
+                        break;
+                    case '>':
+                        buf.append("&gt;");
+                        break;
+                    case '\n':
+                        buf.append("\\n");
+                        break;
+                    case '\r':
+                        buf.append("\\r");
+                        break;
+                    default:
+                        buf.append(ch);
+                }
+            }
+        } catch (StringIndexOutOfBoundsException e) {
+        } // Never occurs
+        return buf.toString();
+    }
+
+
+    private void writeMainHTML( AttributeHTML attribute_html ) throws IOException {
+        PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html"));
+        Attribute[] attributes = java_class.getAttributes();
+        file.println("<HTML>\n" + "<HEAD><TITLE>Documentation for " + class_name + "</TITLE>"
+                + "</HEAD>\n" + "<FRAMESET BORDER=1 cols=\"30%,*\">\n"
+                + "<FRAMESET BORDER=1 rows=\"80%,*\">\n" + "<FRAME NAME=\"ConstantPool\" SRC=\""
+                + class_name + "_cp.html" + "\"\n MARGINWIDTH=\"0\" "
+                + "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n"
+                + "<FRAME NAME=\"Attributes\" SRC=\"" + class_name + "_attributes.html"
+                + "\"\n MARGINWIDTH=\"0\" "
+                + "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n" + "</FRAMESET>\n"
+                + "<FRAMESET BORDER=1 rows=\"80%,*\">\n" + "<FRAME NAME=\"Code\" SRC=\""
+                + class_name + "_code.html\"\n MARGINWIDTH=0 "
+                + "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n"
+                + "<FRAME NAME=\"Methods\" SRC=\"" + class_name
+                + "_methods.html\"\n MARGINWIDTH=0 "
+                + "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n"
+                + "</FRAMESET></FRAMESET></HTML>");
+        file.close();
+        for (int i = 0; i < attributes.length; i++) {
+            attribute_html.writeAttribute(attributes[i], "class" + i);
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassLoader.java b/java/org/apache/tomcat/util/bcel/util/ClassLoader.java
new file mode 100644 (file)
index 0000000..b7be175
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.ByteArrayInputStream;
+import java.util.Hashtable;
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.ConstantClass;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantUtf8;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * <p>Drop in replacement for the standard class loader of the JVM. You can use it
+ * in conjunction with the JavaWrapper to dynamically modify/create classes
+ * as they're requested.</p>
+ *
+ * <p>This class loader recognizes special requests in a distinct
+ * format, i.e., when the name of the requested class contains with
+ * "$$BCEL$$" it calls the createClass() method with that name
+ * (everything bevor the $$BCEL$$ is considered to be the package
+ * name. You can subclass the class loader and override that
+ * method. "Normal" classes class can be modified by overriding the
+ * modifyClass() method which is called just before defineClass().</p>
+ *
+ * <p>There may be a number of packages where you have to use the
+ * default class loader (which may also be faster). You can define the
+ * set of packages where to use the system class loader in the
+ * constructor. The default value contains "java.", "sun.",
+ * "javax."</p>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see JavaWrapper
+ * @see ClassPath
+ */
+public class ClassLoader extends java.lang.ClassLoader {
+
+    public static final String[] DEFAULT_IGNORED_PACKAGES = {
+            "java.", "javax.", "sun."
+    };
+    private Hashtable classes = new Hashtable(); // Hashtable is synchronized thus thread-safe
+    private String[] ignored_packages;
+    private Repository repository = SyntheticRepository.getInstance();
+
+
+    /** Ignored packages are by default ( "java.", "sun.",
+     * "javax."), i.e. loaded by system class loader
+     */
+    public ClassLoader() {
+        this(DEFAULT_IGNORED_PACKAGES);
+    }
+
+
+    /** @param deferTo delegate class loader to use for ignored packages
+     */
+    public ClassLoader(java.lang.ClassLoader deferTo) {
+        super(deferTo);
+        this.ignored_packages = DEFAULT_IGNORED_PACKAGES;
+        this.repository = new ClassLoaderRepository(deferTo);
+    }
+
+
+    /** @param ignored_packages classes contained in these packages will be loaded
+     * with the system class loader
+     */
+    public ClassLoader(String[] ignored_packages) {
+        this.ignored_packages = ignored_packages;
+    }
+
+
+    /** @param ignored_packages classes contained in these packages will be loaded
+     * with the system class loader
+     * @param deferTo delegate class loader to use for ignored packages
+     */
+    public ClassLoader(java.lang.ClassLoader deferTo, String[] ignored_packages) {
+        this(ignored_packages);
+        this.repository = new ClassLoaderRepository(deferTo);
+    }
+
+
+    protected Class loadClass( String class_name, boolean resolve ) throws ClassNotFoundException {
+        Class cl = null;
+        /* First try: lookup hash table.
+         */
+        if ((cl = (Class) classes.get(class_name)) == null) {
+            /* Second try: Load system class using system class loader. You better
+             * don't mess around with them.
+             */
+            for (int i = 0; i < ignored_packages.length; i++) {
+                if (class_name.startsWith(ignored_packages[i])) {
+                    cl = getParent().loadClass(class_name);
+                    break;
+                }
+            }
+            if (cl == null) {
+                JavaClass clazz = null;
+                /* Third try: Special request?
+                 */
+                if (class_name.indexOf("$$BCEL$$") >= 0) {
+                    clazz = createClass(class_name);
+                } else { // Fourth try: Load classes via repository
+                    if ((clazz = repository.loadClass(class_name)) != null) {
+                        clazz = modifyClass(clazz);
+                    } else {
+                        throw new ClassNotFoundException(class_name);
+                    }
+                }
+                if (clazz != null) {
+                    byte[] bytes = clazz.getBytes();
+                    cl = defineClass(class_name, bytes, 0, bytes.length);
+                } else {
+                    cl = Class.forName(class_name);
+                }
+            }
+            if (resolve) {
+                resolveClass(cl);
+            }
+        }
+        classes.put(class_name, cl);
+        return cl;
+    }
+
+
+    /** Override this method if you want to alter a class before it gets actually
+     * loaded. Does nothing by default.
+     */
+    protected JavaClass modifyClass( JavaClass clazz ) {
+        return clazz;
+    }
+
+
+    /** 
+     * Override this method to create you own classes on the fly. The
+     * name contains the special token $$BCEL$$. Everything before that
+     * token is consddered to be a package name. You can encode you own
+     * arguments into the subsequent string. You must regard however not
+     * to use any "illegal" characters, i.e., characters that may not
+     * appear in a Java class name too<br>
+     *
+     * The default implementation interprets the string as a encoded compressed
+     * Java class, unpacks and decodes it with the Utility.decode() method, and
+     * parses the resulting byte array and returns the resulting JavaClass object.
+     *
+     * @param class_name compressed byte code with "$$BCEL$$" in it
+     */
+    protected JavaClass createClass( String class_name ) {
+        int index = class_name.indexOf("$$BCEL$$");
+        String real_name = class_name.substring(index + 8);
+        JavaClass clazz = null;
+        try {
+            byte[] bytes = Utility.decode(real_name, true);
+            ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo");
+            clazz = parser.parse();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            return null;
+        }
+        // Adapt the class name to the passed value
+        ConstantPool cp = clazz.getConstantPool();
+        ConstantClass cl = (ConstantClass) cp.getConstant(clazz.getClassNameIndex(),
+                Constants.CONSTANT_Class);
+        ConstantUtf8 name = (ConstantUtf8) cp.getConstant(cl.getNameIndex(),
+                Constants.CONSTANT_Utf8);
+        name.setBytes(class_name.replace('.', '/'));
+        return clazz;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassLoaderRepository.java b/java/org/apache/tomcat/util/bcel/util/ClassLoaderRepository.java
new file mode 100644 (file)
index 0000000..8cd0bc5
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/**
+ * The repository maintains information about which classes have
+ * been loaded.
+ *
+ * It loads its data from the ClassLoader implementation
+ * passed into its constructor.
+ *
+ * @see org.apache.tomcat.util.bcel.Repository
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public class ClassLoaderRepository implements Repository {
+
+    private java.lang.ClassLoader loader;
+    private Map loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS
+
+
+    public ClassLoaderRepository(java.lang.ClassLoader loader) {
+        this.loader = loader;
+    }
+
+
+    /**
+     * Store a new JavaClass into this Repository.
+     */
+    public void storeClass( JavaClass clazz ) {
+        loadedClasses.put(clazz.getClassName(), clazz);
+        clazz.setRepository(this);
+    }
+
+
+    /**
+     * Remove class from repository
+     */
+    public void removeClass( JavaClass clazz ) {
+        loadedClasses.remove(clazz.getClassName());
+    }
+
+
+    /**
+     * Find an already defined JavaClass.
+     */
+    public JavaClass findClass( String className ) {
+        if (loadedClasses.containsKey(className)) {
+            return (JavaClass) loadedClasses.get(className);
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Lookup a JavaClass object from the Class Name provided.
+     */
+    public JavaClass loadClass( String className ) throws ClassNotFoundException {
+        String classFile = className.replace('.', '/');
+        JavaClass RC = findClass(className);
+        if (RC != null) {
+            return RC;
+        }
+        try {
+            InputStream is = loader.getResourceAsStream(classFile + ".class");
+            if (is == null) {
+                throw new ClassNotFoundException(className + " not found.");
+            }
+            ClassParser parser = new ClassParser(is, className);
+            RC = parser.parse();
+            storeClass(RC);
+            return RC;
+        } catch (IOException e) {
+            throw new ClassNotFoundException(className + " not found: " + e.toString(), e);
+        }
+    }
+
+
+    public JavaClass loadClass( Class clazz ) throws ClassNotFoundException {
+        return loadClass(clazz.getName());
+    }
+
+
+    /** Clear all entries from cache.
+     */
+    public void clear() {
+        loadedClasses.clear();
+    }
+
+
+    /*
+     * @return null
+     */
+    public ClassPath getClassPath() {
+        return null;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassPath.java b/java/org/apache/tomcat/util/bcel/util/ClassPath.java
new file mode 100644 (file)
index 0000000..284a491
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Responsible for loading (class) files from the CLASSPATH. Inspired by
+ * sun.tools.ClassPath.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ */
+public class ClassPath implements Serializable {
+
+    public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
+    private PathEntry[] paths;
+    private String class_path;
+
+
+    /**
+     * Search for classes in given path.
+     */
+    public ClassPath(String class_path) {
+        this.class_path = class_path;
+        List vec = new ArrayList();
+        for (StringTokenizer tok = new StringTokenizer(class_path, System
+                .getProperty("path.separator")); tok.hasMoreTokens();) {
+            String path = tok.nextToken();
+            if (!path.equals("")) {
+                File file = new File(path);
+                try {
+                    if (file.exists()) {
+                        if (file.isDirectory()) {
+                            vec.add(new Dir(path));
+                        } else {
+                            vec.add(new Zip(new ZipFile(file)));
+                        }
+                    }
+                } catch (IOException e) {
+                    System.err.println("CLASSPATH component " + file + ": " + e);
+                }
+            }
+        }
+        paths = new PathEntry[vec.size()];
+        vec.toArray(paths);
+    }
+
+
+    /**
+     * Search for classes in CLASSPATH.
+     * @deprecated Use SYSTEM_CLASS_PATH constant
+     */
+    public ClassPath() {
+        this(getClassPath());
+    }
+
+
+    /** @return used class path string
+     */
+    public String toString() {
+        return class_path;
+    }
+
+
+    public int hashCode() {
+        return class_path.hashCode();
+    }
+
+
+    public boolean equals( Object o ) {
+        if (o instanceof ClassPath) {
+            return class_path.equals(((ClassPath) o).class_path);
+        }
+        return false;
+    }
+
+
+    private static final void getPathComponents( String path, List list ) {
+        if (path != null) {
+            StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
+            while (tok.hasMoreTokens()) {
+                String name = tok.nextToken();
+                File file = new File(name);
+                if (file.exists()) {
+                    list.add(name);
+                }
+            }
+        }
+    }
+
+
+    /** Checks for class path components in the following properties:
+     * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
+     *
+     * @return class path as used by default by BCEL
+     */
+    public static final String getClassPath() {
+        String class_path = System.getProperty("java.class.path");
+        String boot_path = System.getProperty("sun.boot.class.path");
+        String ext_path = System.getProperty("java.ext.dirs");
+        List list = new ArrayList();
+        getPathComponents(class_path, list);
+        getPathComponents(boot_path, list);
+        List dirs = new ArrayList();
+        getPathComponents(ext_path, dirs);
+        for (Iterator e = dirs.iterator(); e.hasNext();) {
+            File ext_dir = new File((String) e.next());
+            String[] extensions = ext_dir.list(new FilenameFilter() {
+
+                public boolean accept( File dir, String name ) {
+                    name = name.toLowerCase(Locale.ENGLISH);
+                    return name.endsWith(".zip") || name.endsWith(".jar");
+                }
+            });
+            if (extensions != null) {
+                for (int i = 0; i < extensions.length; i++) {
+                    list.add(ext_dir.getPath() + File.separatorChar + extensions[i]);
+                }
+            }
+        }
+        StringBuffer buf = new StringBuffer();
+        for (Iterator e = list.iterator(); e.hasNext();) {
+            buf.append((String) e.next());
+            if (e.hasNext()) {
+                buf.append(File.pathSeparatorChar);
+            }
+        }
+        return buf.toString().intern();
+    }
+
+
+    /**
+     * @param name fully qualified class name, e.g. java.lang.String
+     * @return input stream for class
+     */
+    public InputStream getInputStream( String name ) throws IOException {
+        return getInputStream(name.replace('.', '/'), ".class");
+    }
+
+
+    /**
+     * Return stream for class or resource on CLASSPATH.
+     *
+     * @param name fully qualified file name, e.g. java/lang/String
+     * @param suffix file name ends with suff, e.g. .java
+     * @return input stream for file on class path
+     */
+    public InputStream getInputStream( String name, String suffix ) throws IOException {
+        InputStream is = null;
+        try {
+            is = getClass().getClassLoader().getResourceAsStream(name + suffix);
+        } catch (Exception e) {
+        }
+        if (is != null) {
+            return is;
+        }
+        return getClassFile(name, suffix).getInputStream();
+    }
+
+    /**
+     * @param name fully qualified resource name, e.g. java/lang/String.class
+     * @return InputStream supplying the resource, or null if no resource with that name.
+     */
+    public InputStream getResourceAsStream(String name) {
+        for (int i = 0; i < paths.length; i++) {
+            InputStream is;
+            if ((is = paths[i].getResourceAsStream(name)) != null) {
+                return is;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * @param name fully qualified resource name, e.g. java/lang/String.class
+     * @return URL supplying the resource, or null if no resource with that name.
+     */
+    public URL getResource(String name) {
+        for (int i = 0; i < paths.length; i++) {
+            URL url;
+            if ((url = paths[i].getResource(name)) != null) {
+                return url;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param name fully qualified resource name, e.g. java/lang/String.class
+     * @return An Enumeration of URLs supplying the resource, or an
+     * empty Enumeration if no resource with that name.
+     */
+    public Enumeration getResources(String name) {
+        Vector results = new Vector();
+        for (int i = 0; i < paths.length; i++) {
+            URL url;
+            if ((url = paths[i].getResource(name)) != null) {
+                results.add(url);
+            }
+        }
+        return results.elements();
+    }
+
+    /**
+     * @param name fully qualified file name, e.g. java/lang/String
+     * @param suffix file name ends with suff, e.g. .java
+     * @return class file for the java class
+     */
+    public ClassFile getClassFile( String name, String suffix ) throws IOException {
+        for (int i = 0; i < paths.length; i++) {
+            ClassFile cf;
+            if ((cf = paths[i].getClassFile(name, suffix)) != null) {
+                return cf;
+            }
+        }
+        throw new IOException("Couldn't find: " + name + suffix);
+    }
+
+
+    /**
+     * @param name fully qualified class name, e.g. java.lang.String
+     * @return input stream for class
+     */
+    public ClassFile getClassFile( String name ) throws IOException {
+        return getClassFile(name, ".class");
+    }
+
+
+    /**
+     * @param name fully qualified file name, e.g. java/lang/String
+     * @param suffix file name ends with suffix, e.g. .java
+     * @return byte array for file on class path
+     */
+    public byte[] getBytes( String name, String suffix ) throws IOException {
+        DataInputStream dis = null;
+        try {
+            InputStream is = getInputStream(name, suffix);
+            if (is == null) {
+                throw new IOException("Couldn't find: " + name + suffix);
+            }
+            dis = new DataInputStream(is);
+            byte[] bytes = new byte[is.available()];
+            dis.readFully(bytes);
+            return bytes;
+        } finally {
+            if (dis != null) {
+                dis.close();
+            }
+        }
+    }
+
+
+    /**
+     * @return byte array for class
+     */
+    public byte[] getBytes( String name ) throws IOException {
+        return getBytes(name, ".class");
+    }
+
+
+    /**
+     * @param name name of file to search for, e.g. java/lang/String.java
+     * @return full (canonical) path for file
+     */
+    public String getPath( String name ) throws IOException {
+        int index = name.lastIndexOf('.');
+        String suffix = "";
+        if (index > 0) {
+            suffix = name.substring(index);
+            name = name.substring(0, index);
+        }
+        return getPath(name, suffix);
+    }
+
+
+    /**
+     * @param name name of file to search for, e.g. java/lang/String
+     * @param suffix file name suffix, e.g. .java
+     * @return full (canonical) path for file, if it exists
+     */
+    public String getPath( String name, String suffix ) throws IOException {
+        return getClassFile(name, suffix).getPath();
+    }
+
+    private static abstract class PathEntry implements Serializable {
+
+        abstract ClassFile getClassFile( String name, String suffix ) throws IOException;
+        abstract URL getResource(String name);
+        abstract InputStream getResourceAsStream(String name);
+    }
+
+    /** Contains information about file/ZIP entry of the Java class.
+     */
+    public interface ClassFile {
+
+        /** @return input stream for class file.
+         */
+        public abstract InputStream getInputStream() throws IOException;
+
+
+        /** @return canonical path to class file.
+         */
+        public abstract String getPath();
+
+
+        /** @return base path of found class, i.e. class is contained relative
+         * to that path, which may either denote a directory, or zip file
+         */
+        public abstract String getBase();
+
+
+        /** @return modification time of class file.
+         */
+        public abstract long getTime();
+
+
+        /** @return size of class file.
+         */
+        public abstract long getSize();
+    }
+
+    private static class Dir extends PathEntry {
+
+        private String dir;
+
+
+        Dir(String d) {
+            dir = d;
+        }
+
+        URL getResource(String name) {
+            // Resource specification uses '/' whatever the platform
+            final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
+            try {
+                return file.exists() ? file.toURL() : null;
+            } catch (MalformedURLException e) {
+               return null;
+            }
+        }
+        
+        InputStream getResourceAsStream(String name) {
+            // Resource specification uses '/' whatever the platform
+            final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
+            try {
+               return file.exists() ? new FileInputStream(file) : null;
+            } catch (IOException e) {
+               return null;
+            }
+        }
+
+        ClassFile getClassFile( String name, String suffix ) throws IOException {
+            final File file = new File(dir + File.separatorChar
+                    + name.replace('.', File.separatorChar) + suffix);
+            return file.exists() ? new ClassFile() {
+
+                public InputStream getInputStream() throws IOException {
+                    return new FileInputStream(file);
+                }
+
+
+                public String getPath() {
+                    try {
+                        return file.getCanonicalPath();
+                    } catch (IOException e) {
+                        return null;
+                    }
+                }
+
+
+                public long getTime() {
+                    return file.lastModified();
+                }
+
+
+                public long getSize() {
+                    return file.length();
+                }
+
+
+                public String getBase() {
+                    return dir;
+                }
+            } : null;
+        }
+
+
+        public String toString() {
+            return dir;
+        }
+    }
+
+    private static class Zip extends PathEntry {
+
+        private ZipFile zip;
+
+
+        Zip(ZipFile z) {
+            zip = z;
+        }
+
+        URL getResource(String name) {
+            final ZipEntry entry = zip.getEntry(name);
+            try {
+                return (entry != null) ? new URL("jar:file:" + zip.getName() + "!/" + name) : null;
+            } catch (MalformedURLException e) {
+                return null;
+           }
+        }
+        
+        InputStream getResourceAsStream(String name) {
+            final ZipEntry entry = zip.getEntry(name);
+            try {
+                return (entry != null) ? zip.getInputStream(entry) : null;
+            } catch (IOException e) {
+                return null;
+            }
+        }
+               
+        ClassFile getClassFile( String name, String suffix ) throws IOException {
+            final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
+            
+            if (entry == null)
+               return null;
+            
+            return new ClassFile() {
+
+                public InputStream getInputStream() throws IOException {
+                    return zip.getInputStream(entry);
+                }
+
+
+                public String getPath() {
+                    return entry.toString();
+                }
+
+
+                public long getTime() {
+                    return entry.getTime();
+                }
+
+
+                public long getSize() {
+                    return entry.getSize();
+                }
+
+
+                public String getBase() {
+                    return zip.getName();
+                }
+            };
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassQueue.java b/java/org/apache/tomcat/util/bcel/util/ClassQueue.java
new file mode 100644 (file)
index 0000000..0f5239e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.util.LinkedList;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/** 
+ * Utility class implementing a (typesafe) queue of JavaClass
+ * objects.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ */
+public class ClassQueue implements java.io.Serializable {
+
+    protected LinkedList vec = new LinkedList();
+
+
+    public void enqueue( JavaClass clazz ) {
+        vec.addLast(clazz);
+    }
+
+
+    public JavaClass dequeue() {
+        return (JavaClass) vec.removeFirst();
+    }
+
+
+    public boolean empty() {
+        return vec.isEmpty();
+    }
+
+
+    public String toString() {
+        return vec.toString();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassSet.java b/java/org/apache/tomcat/util/bcel/util/ClassSet.java
new file mode 100644 (file)
index 0000000..1acc5da
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/** 
+ * Utility class implementing a (typesafe) set of JavaClass objects.
+ * Since JavaClass has no equals() method, the name of the class is
+ * used for comparison.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ * @see ClassStack
+ */
+public class ClassSet implements java.io.Serializable {
+
+    private Map _map = new HashMap();
+
+
+    public boolean add( JavaClass clazz ) {
+        boolean result = false;
+        if (!_map.containsKey(clazz.getClassName())) {
+            result = true;
+            _map.put(clazz.getClassName(), clazz);
+        }
+        return result;
+    }
+
+
+    public void remove( JavaClass clazz ) {
+        _map.remove(clazz.getClassName());
+    }
+
+
+    public boolean empty() {
+        return _map.isEmpty();
+    }
+
+
+    public JavaClass[] toArray() {
+        Collection values = _map.values();
+        JavaClass[] classes = new JavaClass[values.size()];
+        values.toArray(classes);
+        return classes;
+    }
+
+
+    public String[] getClassNames() {
+        return (String[]) _map.keySet().toArray(new String[_map.keySet().size()]);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassStack.java b/java/org/apache/tomcat/util/bcel/util/ClassStack.java
new file mode 100644 (file)
index 0000000..cd54559
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.util.Stack;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/** 
+ * Utility class implementing a (typesafe) stack of JavaClass objects.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ * @see Stack
+ */
+public class ClassStack implements java.io.Serializable {
+
+    private Stack stack = new Stack();
+
+
+    public void push( JavaClass clazz ) {
+        stack.push(clazz);
+    }
+
+
+    public JavaClass pop() {
+        return (JavaClass) stack.pop();
+    }
+
+
+    public JavaClass top() {
+        return (JavaClass) stack.peek();
+    }
+
+
+    public boolean empty() {
+        return stack.empty();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ClassVector.java b/java/org/apache/tomcat/util/bcel/util/ClassVector.java
new file mode 100644 (file)
index 0000000..1ab3870
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/** 
+ * Utility class implementing a (typesafe) collection of JavaClass
+ * objects. Contains the most important methods of a Vector.
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> 
+ * 
+ * @deprecated as of 5.1.1 - 7/17/2005
+ */
+public class ClassVector implements java.io.Serializable {
+
+    protected List vec = new ArrayList();
+
+
+    public void addElement( JavaClass clazz ) {
+        vec.add(clazz);
+    }
+
+
+    public JavaClass elementAt( int index ) {
+        return (JavaClass) vec.get(index);
+    }
+
+
+    public void removeElementAt( int index ) {
+        vec.remove(index);
+    }
+
+
+    public JavaClass[] toArray() {
+        JavaClass[] classes = new JavaClass[vec.size()];
+        vec.toArray(classes);
+        return classes;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/CodeHTML.java b/java/org/apache/tomcat/util/bcel/util/CodeHTML.java
new file mode 100644 (file)
index 0000000..d09b5c4
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.BitSet;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Code;
+import org.apache.tomcat.util.bcel.classfile.CodeException;
+import org.apache.tomcat.util.bcel.classfile.ConstantFieldref;
+import org.apache.tomcat.util.bcel.classfile.ConstantInterfaceMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantNameAndType;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.LocalVariable;
+import org.apache.tomcat.util.bcel.classfile.LocalVariableTable;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Convert code into HTML file.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * 
+ */
+final class CodeHTML implements org.apache.tomcat.util.bcel.Constants {
+
+    private String class_name; // name of current class
+//    private Method[] methods; // Methods to print
+    private PrintWriter file; // file to write to
+    private BitSet goto_set;
+    private ConstantPool constant_pool;
+    private ConstantHTML constant_html;
+    private static boolean wide = false;
+
+
+    CodeHTML(String dir, String class_name, Method[] methods, ConstantPool constant_pool,
+            ConstantHTML constant_html) throws IOException {
+        this.class_name = class_name;
+//        this.methods = methods;
+        this.constant_pool = constant_pool;
+        this.constant_html = constant_html;
+        file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html"));
+        file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\">");
+        for (int i = 0; i < methods.length; i++) {
+            writeMethod(methods[i], i);
+        }
+        file.println("</BODY></HTML>");
+        file.close();
+    }
+
+
+    /**
+     * Disassemble a stream of byte codes and return the
+     * string representation.
+     *
+     * @param  stream data input stream
+     * @return String representation of byte code
+     */
+    private final String codeToHTML( ByteSequence bytes, int method_number ) throws IOException {
+        short opcode = (short) bytes.readUnsignedByte();
+        StringBuffer buf;
+        String name, signature;
+        int default_offset = 0, low, high;
+        int index, class_index, vindex, constant;
+        int[] jump_table;
+        int no_pad_bytes = 0, offset;
+        buf = new StringBuffer(256);
+        buf.append("<TT>").append(OPCODE_NAMES[opcode]).append("</TT></TD><TD>");
+        /* Special case: Skip (0-3) padding bytes, i.e., the
+         * following bytes are 4-byte-aligned
+         */
+        if ((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) {
+            int remainder = bytes.getIndex() % 4;
+            no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
+            for (int i = 0; i < no_pad_bytes; i++) {
+                bytes.readByte();
+            }
+            // Both cases have a field default_offset in common
+            default_offset = bytes.readInt();
+        }
+        switch (opcode) {
+            case TABLESWITCH:
+                low = bytes.readInt();
+                high = bytes.readInt();
+                offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
+                default_offset += offset;
+                buf.append("<TABLE BORDER=1><TR>");
+                // Print switch indices in first row (and default)
+                jump_table = new int[high - low + 1];
+                for (int i = 0; i < jump_table.length; i++) {
+                    jump_table[i] = offset + bytes.readInt();
+                    buf.append("<TH>").append(low + i).append("</TH>");
+                }
+                buf.append("<TH>default</TH></TR>\n<TR>");
+                // Print target and default indices in second row
+                for (int i = 0; i < jump_table.length; i++) {
+                    buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+                            jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
+                }
+                buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+                        default_offset).append("\">").append(default_offset).append(
+                        "</A></TD></TR>\n</TABLE>\n");
+                break;
+            /* Lookup switch has variable length arguments.
+             */
+            case LOOKUPSWITCH:
+                int npairs = bytes.readInt();
+                offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
+                jump_table = new int[npairs];
+                default_offset += offset;
+                buf.append("<TABLE BORDER=1><TR>");
+                // Print switch indices in first row (and default)
+                for (int i = 0; i < npairs; i++) {
+                    int match = bytes.readInt();
+                    jump_table[i] = offset + bytes.readInt();
+                    buf.append("<TH>").append(match).append("</TH>");
+                }
+                buf.append("<TH>default</TH></TR>\n<TR>");
+                // Print target and default indices in second row
+                for (int i = 0; i < npairs; i++) {
+                    buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+                            jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
+                }
+                buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+                        default_offset).append("\">").append(default_offset).append(
+                        "</A></TD></TR>\n</TABLE>\n");
+                break;
+            /* Two address bytes + offset from start of byte stream form the
+             * jump target.
+             */
+            case GOTO:
+            case IFEQ:
+            case IFGE:
+            case IFGT:
+            case IFLE:
+            case IFLT:
+            case IFNE:
+            case IFNONNULL:
+            case IFNULL:
+            case IF_ACMPEQ:
+            case IF_ACMPNE:
+            case IF_ICMPEQ:
+            case IF_ICMPGE:
+            case IF_ICMPGT:
+            case IF_ICMPLE:
+            case IF_ICMPLT:
+            case IF_ICMPNE:
+            case JSR:
+                index = (int) (bytes.getIndex() + bytes.readShort() - 1);
+                buf.append("<A HREF=\"#code").append(method_number).append("@").append(index)
+                        .append("\">").append(index).append("</A>");
+                break;
+            /* Same for 32-bit wide jumps
+             */
+            case GOTO_W:
+            case JSR_W:
+                int windex = bytes.getIndex() + bytes.readInt() - 1;
+                buf.append("<A HREF=\"#code").append(method_number).append("@").append(windex)
+                        .append("\">").append(windex).append("</A>");
+                break;
+            /* Index byte references local variable (register)
+             */
+            case ALOAD:
+            case ASTORE:
+            case DLOAD:
+            case DSTORE:
+            case FLOAD:
+            case FSTORE:
+            case ILOAD:
+            case ISTORE:
+            case LLOAD:
+            case LSTORE:
+            case RET:
+                if (wide) {
+                    vindex = bytes.readShort();
+                    wide = false; // Clear flag
+                } else {
+                    vindex = bytes.readUnsignedByte();
+                }
+                buf.append("%").append(vindex);
+                break;
+            /*
+             * Remember wide byte which is used to form a 16-bit address in the
+             * following instruction. Relies on that the method is called again with
+             * the following opcode.
+             */
+            case WIDE:
+                wide = true;
+                buf.append("(wide)");
+                break;
+            /* Array of basic type.
+             */
+            case NEWARRAY:
+                buf.append("<FONT COLOR=\"#00FF00\">").append(TYPE_NAMES[bytes.readByte()]).append(
+                        "</FONT>");
+                break;
+            /* Access object/class fields.
+             */
+            case GETFIELD:
+            case GETSTATIC:
+            case PUTFIELD:
+            case PUTSTATIC:
+                index = bytes.readShort();
+                ConstantFieldref c1 = (ConstantFieldref) constant_pool.getConstant(index,
+                        CONSTANT_Fieldref);
+                class_index = c1.getClassIndex();
+                name = constant_pool.getConstantString(class_index, CONSTANT_Class);
+                name = Utility.compactClassName(name, false);
+                index = c1.getNameAndTypeIndex();
+                String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType);
+                if (name.equals(class_name)) { // Local field
+                    buf.append("<A HREF=\"").append(class_name).append("_methods.html#field")
+                            .append(field_name).append("\" TARGET=Methods>").append(field_name)
+                            .append("</A>\n");
+                } else {
+                    buf.append(constant_html.referenceConstant(class_index)).append(".").append(
+                            field_name);
+                }
+                break;
+            /* Operands are references to classes in constant pool
+             */
+            case CHECKCAST:
+            case INSTANCEOF:
+            case NEW:
+                index = bytes.readShort();
+                buf.append(constant_html.referenceConstant(index));
+                break;
+            /* Operands are references to methods in constant pool
+             */
+            case INVOKESPECIAL:
+            case INVOKESTATIC:
+            case INVOKEVIRTUAL:
+            case INVOKEINTERFACE:
+                int m_index = bytes.readShort();
+                String str;
+                if (opcode == INVOKEINTERFACE) { // Special treatment needed
+                    bytes.readUnsignedByte(); // Redundant
+                    bytes.readUnsignedByte(); // Reserved
+//                    int nargs = bytes.readUnsignedByte(); // Redundant
+//                    int reserved = bytes.readUnsignedByte(); // Reserved
+                    ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool
+                            .getConstant(m_index, CONSTANT_InterfaceMethodref);
+                    class_index = c.getClassIndex();
+                    str = constant_pool.constantToString(c);
+                    index = c.getNameAndTypeIndex();
+                } else {
+                    ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index,
+                            CONSTANT_Methodref);
+                    class_index = c.getClassIndex();
+                    str = constant_pool.constantToString(c);
+                    index = c.getNameAndTypeIndex();
+                }
+                name = Class2HTML.referenceClass(class_index);
+                str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(
+                        index, CONSTANT_NameAndType)));
+                // Get signature, i.e., types
+                ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(index,
+                        CONSTANT_NameAndType);
+                signature = constant_pool.constantToString(c2.getSignatureIndex(), CONSTANT_Utf8);
+                String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+                String type = Utility.methodSignatureReturnType(signature, false);
+                buf.append(name).append(".<A HREF=\"").append(class_name).append("_cp.html#cp")
+                        .append(m_index).append("\" TARGET=ConstantPool>").append(str).append(
+                                "</A>").append("(");
+                // List arguments
+                for (int i = 0; i < args.length; i++) {
+                    buf.append(Class2HTML.referenceType(args[i]));
+                    if (i < args.length - 1) {
+                        buf.append(", ");
+                    }
+                }
+                // Attach return type
+                buf.append("):").append(Class2HTML.referenceType(type));
+                break;
+            /* Operands are references to items in constant pool
+             */
+            case LDC_W:
+            case LDC2_W:
+                index = bytes.readShort();
+                buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
+                        .append("\" TARGET=\"ConstantPool\">").append(
+                                Class2HTML.toHTML(constant_pool.constantToString(index,
+                                        constant_pool.getConstant(index).getTag()))).append("</a>");
+                break;
+            case LDC:
+                index = bytes.readUnsignedByte();
+                buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
+                        .append("\" TARGET=\"ConstantPool\">").append(
+                                Class2HTML.toHTML(constant_pool.constantToString(index,
+                                        constant_pool.getConstant(index).getTag()))).append("</a>");
+                break;
+            /* Array of references.
+             */
+            case ANEWARRAY:
+                index = bytes.readShort();
+                buf.append(constant_html.referenceConstant(index));
+                break;
+            /* Multidimensional array of references.
+             */
+            case MULTIANEWARRAY:
+                index = bytes.readShort();
+                int dimensions = bytes.readByte();
+                buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions)
+                        .append("-dimensional");
+                break;
+            /* Increment local variable.
+             */
+            case IINC:
+                if (wide) {
+                    vindex = bytes.readShort();
+                    constant = bytes.readShort();
+                    wide = false;
+                } else {
+                    vindex = bytes.readUnsignedByte();
+                    constant = bytes.readByte();
+                }
+                buf.append("%").append(vindex).append(" ").append(constant);
+                break;
+            default:
+                if (NO_OF_OPERANDS[opcode] > 0) {
+                    for (int i = 0; i < TYPE_OF_OPERANDS[opcode].length; i++) {
+                        switch (TYPE_OF_OPERANDS[opcode][i]) {
+                            case T_BYTE:
+                                buf.append(bytes.readUnsignedByte());
+                                break;
+                            case T_SHORT: // Either branch or index
+                                buf.append(bytes.readShort());
+                                break;
+                            case T_INT:
+                                buf.append(bytes.readInt());
+                                break;
+                            default: // Never reached
+                                System.err.println("Unreachable default case reached!");
+                                System.exit(-1);
+                        }
+                        buf.append("&nbsp;");
+                    }
+                }
+        }
+        buf.append("</TD>");
+        return buf.toString();
+    }
+
+
+    /**
+     * Find all target addresses in code, so that they can be marked
+     * with &lt;A NAME = ...&gt;. Target addresses are kept in an BitSet object.
+     */
+    private final void findGotos( ByteSequence bytes, Method method, Code code ) throws IOException {
+        int index;
+        goto_set = new BitSet(bytes.available());
+        int opcode;
+        /* First get Code attribute from method and the exceptions handled
+         * (try .. catch) in this method. We only need the line number here.
+         */
+        if (code != null) {
+            CodeException[] ce = code.getExceptionTable();
+            int len = ce.length;
+            for (int i = 0; i < len; i++) {
+                goto_set.set(ce[i].getStartPC());
+                goto_set.set(ce[i].getEndPC());
+                goto_set.set(ce[i].getHandlerPC());
+            }
+            // Look for local variables and their range
+            Attribute[] attributes = code.getAttributes();
+            for (int i = 0; i < attributes.length; i++) {
+                if (attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) {
+                    LocalVariable[] vars = ((LocalVariableTable) attributes[i])
+                            .getLocalVariableTable();
+                    for (int j = 0; j < vars.length; j++) {
+                        int start = vars[j].getStartPC();
+                        int end = (int) (start + vars[j].getLength());
+                        goto_set.set(start);
+                        goto_set.set(end);
+                    }
+                    break;
+                }
+            }
+        }
+        // Get target addresses from GOTO, JSR, TABLESWITCH, etc.
+        for (int i = 0; bytes.available() > 0; i++) {
+            opcode = bytes.readUnsignedByte();
+            //System.out.println(OPCODE_NAMES[opcode]);
+            switch (opcode) {
+                case TABLESWITCH:
+                case LOOKUPSWITCH:
+                    //bytes.readByte(); // Skip already read byte
+                    int remainder = bytes.getIndex() % 4;
+                    int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
+                    int default_offset,
+                    offset;
+                    for (int j = 0; j < no_pad_bytes; j++) {
+                        bytes.readByte();
+                    }
+                    // Both cases have a field default_offset in common
+                    default_offset = bytes.readInt();
+                    if (opcode == TABLESWITCH) {
+                        int low = bytes.readInt();
+                        int high = bytes.readInt();
+                        offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
+                        default_offset += offset;
+                        goto_set.set(default_offset);
+                        for (int j = 0; j < (high - low + 1); j++) {
+                            index = offset + bytes.readInt();
+                            goto_set.set(index);
+                        }
+                    } else { // LOOKUPSWITCH
+                        int npairs = bytes.readInt();
+                        offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
+                        default_offset += offset;
+                        goto_set.set(default_offset);
+                        for (int j = 0; j < npairs; j++) {
+//                            int match = bytes.readInt();
+                            bytes.readInt();
+                            index = offset + bytes.readInt();
+                            goto_set.set(index);
+                        }
+                    }
+                    break;
+                case GOTO:
+                case IFEQ:
+                case IFGE:
+                case IFGT:
+                case IFLE:
+                case IFLT:
+                case IFNE:
+                case IFNONNULL:
+                case IFNULL:
+                case IF_ACMPEQ:
+                case IF_ACMPNE:
+                case IF_ICMPEQ:
+                case IF_ICMPGE:
+                case IF_ICMPGT:
+                case IF_ICMPLE:
+                case IF_ICMPLT:
+                case IF_ICMPNE:
+                case JSR:
+                    //bytes.readByte(); // Skip already read byte
+                    index = bytes.getIndex() + bytes.readShort() - 1;
+                    goto_set.set(index);
+                    break;
+                case GOTO_W:
+                case JSR_W:
+                    //bytes.readByte(); // Skip already read byte
+                    index = bytes.getIndex() + bytes.readInt() - 1;
+                    goto_set.set(index);
+                    break;
+                default:
+                    bytes.unreadByte();
+                    codeToHTML(bytes, 0); // Ignore output
+            }
+        }
+    }
+
+
+    /**
+     * Write a single method with the byte code associated with it.
+     */
+    private void writeMethod( Method method, int method_number ) throws IOException {
+        // Get raw signature
+        String signature = method.getSignature();
+        // Get array of strings containing the argument types
+        String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+        // Get return type string
+        String type = Utility.methodSignatureReturnType(signature, false);
+        // Get method name
+        String name = method.getName();
+        String html_name = Class2HTML.toHTML(name);
+        // Get method's access flags
+        String access = Utility.accessToString(method.getAccessFlags());
+        access = Utility.replace(access, " ", "&nbsp;");
+        // Get the method's attributes, the Code Attribute in particular
+        Attribute[] attributes = method.getAttributes();
+        file.print("<P><B><FONT COLOR=\"#FF0000\">" + access + "</FONT>&nbsp;" + "<A NAME=method"
+                + method_number + ">" + Class2HTML.referenceType(type) + "</A>&nbsp<A HREF=\""
+                + class_name + "_methods.html#method" + method_number + "\" TARGET=Methods>"
+                + html_name + "</A>(");
+        for (int i = 0; i < args.length; i++) {
+            file.print(Class2HTML.referenceType(args[i]));
+            if (i < args.length - 1) {
+                file.print(",&nbsp;");
+            }
+        }
+        file.println(")</B></P>");
+        Code c = null;
+        byte[] code = null;
+        if (attributes.length > 0) {
+            file.print("<H4>Attributes</H4><UL>\n");
+            for (int i = 0; i < attributes.length; i++) {
+                byte tag = attributes[i].getTag();
+                if (tag != ATTR_UNKNOWN) {
+                    file.print("<LI><A HREF=\"" + class_name + "_attributes.html#method"
+                            + method_number + "@" + i + "\" TARGET=Attributes>"
+                            + ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
+                } else {
+                    file.print("<LI>" + attributes[i] + "</LI>");
+                }
+                if (tag == ATTR_CODE) {
+                    c = (Code) attributes[i];
+                    Attribute[] attributes2 = c.getAttributes();
+                    code = c.getCode();
+                    file.print("<UL>");
+                    for (int j = 0; j < attributes2.length; j++) {
+                        tag = attributes2[j].getTag();
+                        file.print("<LI><A HREF=\"" + class_name + "_attributes.html#" + "method"
+                                + method_number + "@" + i + "@" + j + "\" TARGET=Attributes>"
+                                + ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
+                    }
+                    file.print("</UL>");
+                }
+            }
+            file.println("</UL>");
+        }
+        if (code != null) { // No code, an abstract method, e.g.
+            //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1));
+            // Print the byte code
+            ByteSequence stream = new ByteSequence(code);
+            stream.mark(stream.available());
+            findGotos(stream, method, c);
+            stream.reset();
+            file.println("<TABLE BORDER=0><TR><TH ALIGN=LEFT>Byte<BR>offset</TH>"
+                    + "<TH ALIGN=LEFT>Instruction</TH><TH ALIGN=LEFT>Argument</TH>");
+            for (int i = 0; stream.available() > 0; i++) {
+                int offset = stream.getIndex();
+                String str = codeToHTML(stream, method_number);
+                String anchor = "";
+                /* Set an anchor mark if this line is targetted by a goto, jsr, etc.
+                 * Defining an anchor for every line is very inefficient!
+                 */
+                if (goto_set.get(offset)) {
+                    anchor = "<A NAME=code" + method_number + "@" + offset + "></A>";
+                }
+                String anchor2;
+                if (stream.getIndex() == code.length) {
+                    anchor2 = "<A NAME=code" + method_number + "@" + code.length + ">" + offset
+                            + "</A>";
+                } else {
+                    anchor2 = "" + offset;
+                }
+                file
+                        .println("<TR VALIGN=TOP><TD>" + anchor2 + "</TD><TD>" + anchor + str
+                                + "</TR>");
+            }
+            // Mark last line, may be targetted from Attributes window
+            file.println("<TR><TD> </A></TD></TR>");
+            file.println("</TABLE>");
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/ConstantHTML.java b/java/org/apache/tomcat/util/bcel/util/ConstantHTML.java
new file mode 100644 (file)
index 0000000..ea56a6e
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import org.apache.tomcat.util.bcel.classfile.Constant;
+import org.apache.tomcat.util.bcel.classfile.ConstantClass;
+import org.apache.tomcat.util.bcel.classfile.ConstantFieldref;
+import org.apache.tomcat.util.bcel.classfile.ConstantInterfaceMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantMethodref;
+import org.apache.tomcat.util.bcel.classfile.ConstantNameAndType;
+import org.apache.tomcat.util.bcel.classfile.ConstantPool;
+import org.apache.tomcat.util.bcel.classfile.ConstantString;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Convert constant pool into HTML file.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * 
+ */
+final class ConstantHTML implements org.apache.tomcat.util.bcel.Constants {
+
+    private String class_name; // name of current class
+    private String class_package; // name of package
+    private ConstantPool constant_pool; // reference to constant pool
+    private PrintWriter file; // file to write to
+    private String[] constant_ref; // String to return for cp[i]
+    private Constant[] constants; // The constants in the cp
+    private Method[] methods;
+
+
+    ConstantHTML(String dir, String class_name, String class_package, Method[] methods,
+            ConstantPool constant_pool) throws IOException {
+        this.class_name = class_name;
+        this.class_package = class_package;
+        this.constant_pool = constant_pool;
+        this.methods = methods;
+        constants = constant_pool.getConstantPool();
+        file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html"));
+        constant_ref = new String[constants.length];
+        constant_ref[0] = "&lt;unknown&gt;";
+        file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>");
+        // Loop through constants, constants[0] is reserved
+        for (int i = 1; i < constants.length; i++) {
+            if (i % 2 == 0) {
+                file.print("<TR BGCOLOR=\"#C0C0C0\"><TD>");
+            } else {
+                file.print("<TR BGCOLOR=\"#A0A0A0\"><TD>");
+            }
+            if (constants[i] != null) {
+                writeConstant(i);
+            }
+            file.print("</TD></TR>\n");
+        }
+        file.println("</TABLE></BODY></HTML>");
+        file.close();
+    }
+
+
+    String referenceConstant( int index ) {
+        return constant_ref[index];
+    }
+
+
+    private void writeConstant( int index ) {
+        byte tag = constants[index].getTag();
+        int class_index, name_index;
+        String ref;
+        // The header is always the same
+        file.println("<H4> <A NAME=cp" + index + ">" + index + "</A> " + CONSTANT_NAMES[tag]
+                + "</H4>");
+        /* For every constant type get the needed parameters and print them appropiately 
+         */
+        switch (tag) {
+            case CONSTANT_InterfaceMethodref:
+            case CONSTANT_Methodref:
+                // Get class_index and name_and_type_index, depending on type
+                if (tag == CONSTANT_Methodref) {
+                    ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index,
+                            CONSTANT_Methodref);
+                    class_index = c.getClassIndex();
+                    name_index = c.getNameAndTypeIndex();
+                } else {
+                    ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool
+                            .getConstant(index, CONSTANT_InterfaceMethodref);
+                    class_index = c1.getClassIndex();
+                    name_index = c1.getNameAndTypeIndex();
+                }
+                // Get method name and its class
+                String method_name = constant_pool.constantToString(name_index,
+                        CONSTANT_NameAndType);
+                String html_method_name = Class2HTML.toHTML(method_name);
+                // Partially compacted class name, i.e., / -> .
+                String method_class = constant_pool.constantToString(class_index, CONSTANT_Class);
+                String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang.
+                short_method_class = Utility.compactClassName(short_method_class, class_package
+                        + ".", true); // Remove class package prefix
+                // Get method signature
+                ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(
+                        name_index, CONSTANT_NameAndType);
+                String signature = constant_pool.constantToString(c2.getSignatureIndex(),
+                        CONSTANT_Utf8);
+                // Get array of strings containing the argument types
+                String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+                // Get return type string
+                String type = Utility.methodSignatureReturnType(signature, false);
+                String ret_type = Class2HTML.referenceType(type);
+                StringBuffer buf = new StringBuffer("(");
+                for (int i = 0; i < args.length; i++) {
+                    buf.append(Class2HTML.referenceType(args[i]));
+                    if (i < args.length - 1) {
+                        buf.append(",&nbsp;");
+                    }
+                }
+                buf.append(")");
+                String arg_types = buf.toString();
+                if (method_class.equals(class_name)) {
+                    ref = "<A HREF=\"" + class_name + "_code.html#method"
+                            + getMethodNumber(method_name + signature) + "\" TARGET=Code>"
+                            + html_method_name + "</A>";
+                } else {
+                    ref = "<A HREF=\"" + method_class + ".html" + "\" TARGET=_top>"
+                            + short_method_class + "</A>." + html_method_name;
+                }
+                constant_ref[index] = ret_type + "&nbsp;<A HREF=\"" + class_name + "_cp.html#cp"
+                        + class_index + "\" TARGET=Constants>" + short_method_class
+                        + "</A>.<A HREF=\"" + class_name + "_cp.html#cp" + index
+                        + "\" TARGET=ConstantPool>" + html_method_name + "</A>&nbsp;" + arg_types;
+                file.println("<P><TT>" + ret_type + "&nbsp;" + ref + arg_types
+                        + "&nbsp;</TT>\n<UL>" + "<LI><A HREF=\"#cp" + class_index
+                        + "\">Class index(" + class_index + ")</A>\n" + "<LI><A HREF=\"#cp"
+                        + name_index + "\">NameAndType index(" + name_index + ")</A></UL>");
+                break;
+            case CONSTANT_Fieldref:
+                // Get class_index and name_and_type_index
+                ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index,
+                        CONSTANT_Fieldref);
+                class_index = c3.getClassIndex();
+                name_index = c3.getNameAndTypeIndex();
+                // Get method name and its class (compacted)
+                String field_class = constant_pool.constantToString(class_index, CONSTANT_Class);
+                String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang.
+                short_field_class = Utility.compactClassName(short_field_class,
+                        class_package + ".", true); // Remove class package prefix
+                String field_name = constant_pool
+                        .constantToString(name_index, CONSTANT_NameAndType);
+                if (field_class.equals(class_name)) {
+                    ref = "<A HREF=\"" + field_class + "_methods.html#field" + field_name
+                            + "\" TARGET=Methods>" + field_name + "</A>";
+                } else {
+                    ref = "<A HREF=\"" + field_class + ".html\" TARGET=_top>" + short_field_class
+                            + "</A>." + field_name + "\n";
+                }
+                constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + class_index
+                        + "\" TARGET=Constants>" + short_field_class + "</A>.<A HREF=\""
+                        + class_name + "_cp.html#cp" + index + "\" TARGET=ConstantPool>"
+                        + field_name + "</A>";
+                file.println("<P><TT>" + ref + "</TT><BR>\n" + "<UL>" + "<LI><A HREF=\"#cp"
+                        + class_index + "\">Class(" + class_index + ")</A><BR>\n"
+                        + "<LI><A HREF=\"#cp" + name_index + "\">NameAndType(" + name_index
+                        + ")</A></UL>");
+                break;
+            case CONSTANT_Class:
+                ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, CONSTANT_Class);
+                name_index = c4.getNameIndex();
+                String class_name2 = constant_pool.constantToString(index, tag); // / -> .
+                String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang.
+                short_class_name = Utility.compactClassName(short_class_name, class_package + ".",
+                        true); // Remove class package prefix
+                ref = "<A HREF=\"" + class_name2 + ".html\" TARGET=_top>" + short_class_name
+                        + "</A>";
+                constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + index
+                        + "\" TARGET=ConstantPool>" + short_class_name + "</A>";
+                file.println("<P><TT>" + ref + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index
+                        + "\">Name index(" + name_index + ")</A></UL>\n");
+                break;
+            case CONSTANT_String:
+                ConstantString c5 = (ConstantString) constant_pool.getConstant(index,
+                        CONSTANT_String);
+                name_index = c5.getStringIndex();
+                String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag));
+                file.println("<P><TT>" + str + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index
+                        + "\">Name index(" + name_index + ")</A></UL>\n");
+                break;
+            case CONSTANT_NameAndType:
+                ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index,
+                        CONSTANT_NameAndType);
+                name_index = c6.getNameIndex();
+                int signature_index = c6.getSignatureIndex();
+                file.println("<P><TT>"
+                        + Class2HTML.toHTML(constant_pool.constantToString(index, tag))
+                        + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index + "\">Name index("
+                        + name_index + ")</A>\n" + "<LI><A HREF=\"#cp" + signature_index
+                        + "\">Signature index(" + signature_index + ")</A></UL>\n");
+                break;
+            default:
+                file
+                        .println("<P><TT>"
+                                + Class2HTML.toHTML(constant_pool.constantToString(index, tag))
+                                + "</TT>\n");
+        } // switch
+    }
+
+
+    private final int getMethodNumber( String str ) {
+        for (int i = 0; i < methods.length; i++) {
+            String cmp = methods[i].getName() + methods[i].getSignature();
+            if (cmp.equals(str)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/InstructionFinder.java b/java/org/apache/tomcat/util/bcel/util/InstructionFinder.java
new file mode 100644 (file)
index 0000000..16d2a1b
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tomcat.util.bcel.Constants;
+import org.apache.tomcat.util.bcel.generic.ClassGenException;
+import org.apache.tomcat.util.bcel.generic.Instruction;
+import org.apache.tomcat.util.bcel.generic.InstructionHandle;
+import org.apache.tomcat.util.bcel.generic.InstructionList;
+
+/**
+ * InstructionFinder is a tool to search for given instructions patterns, i.e.,
+ * match sequences of instructions in an instruction list via regular
+ * expressions. This can be used, e.g., in order to implement a peep hole
+ * optimizer that looks for code patterns and replaces them with faster
+ * equivalents.
+ * 
+ * <p>
+ * This class internally uses the java.util.regex
+ * package to search for regular expressions.
+ * 
+ * A typical application would look like this:
+ * 
+ * <pre>
+ * 
+ *  
+ *   InstructionFinder f   = new InstructionFinder(il);
+ *   String            pat = &quot;IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)&quot;;
+ *   
+ *   for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
+ *   InstructionHandle[] match = (InstructionHandle[])i.next();
+ *   ...
+ *   il.delete(match[1], match[5]);
+ *   ...
+ *   }
+ *   
+ *  
+ * </pre>
+ * 
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see Instruction
+ * @see InstructionList
+ */
+public class InstructionFinder {
+
+    private static final int OFFSET = 32767; // char + OFFSET is
+    // outside of
+    // LATIN-1
+    private static final int NO_OPCODES = 256; // Potential number,
+    // some are not used
+    private static final Map map = new HashMap(); // Map<String,Pattern>
+    private InstructionList il;
+    private String il_string; // instruction list
+    // as string
+    private InstructionHandle[] handles; // map instruction
+
+
+    // list to array
+    /**
+     * @param il
+     *          instruction list to search for given patterns
+     */
+    public InstructionFinder(InstructionList il) {
+        this.il = il;
+        reread();
+    }
+
+
+    /**
+     * Reread the instruction list, e.g., after you've altered the list upon a
+     * match.
+     */
+    public final void reread() {
+        int size = il.getLength();
+        char[] buf = new char[size]; // Create a string with length equal to il
+        // length
+        handles = il.getInstructionHandles();
+        // Map opcodes to characters
+        for (int i = 0; i < size; i++) {
+            buf[i] = makeChar(handles[i].getInstruction().getOpcode());
+        }
+        il_string = new String(buf);
+    }
+
+
+    /**
+     * Map symbolic instruction names like "getfield" to a single character.
+     * 
+     * @param pattern
+     *          instruction pattern in lower case
+     * @return encoded string for a pattern such as "BranchInstruction".
+     */
+    private static final String mapName( String pattern ) {
+        String result = (String) map.get(pattern);
+        if (result != null) {
+            return result;
+        }
+        for (short i = 0; i < NO_OPCODES; i++) {
+            if (pattern.equals(Constants.OPCODE_NAMES[i])) {
+                return "" + makeChar(i);
+            }
+        }
+        throw new RuntimeException("Instruction unknown: " + pattern);
+    }
+
+
+    /**
+     * Replace symbolic names of instructions with the appropiate character and
+     * remove all white space from string. Meta characters such as +, * are
+     * ignored.
+     * 
+     * @param pattern
+     *          The pattern to compile
+     * @return translated regular expression string
+     */
+    private static final String compilePattern( String pattern ) {
+        //Bug: 38787 - Instructions are assumed to be english, to avoid odd Locale issues
+        String lower = pattern.toLowerCase(Locale.ENGLISH);
+        StringBuffer buf = new StringBuffer();
+        int size = pattern.length();
+        for (int i = 0; i < size; i++) {
+            char ch = lower.charAt(i);
+            if (Character.isLetterOrDigit(ch)) {
+                StringBuffer name = new StringBuffer();
+                while ((Character.isLetterOrDigit(ch) || ch == '_') && i < size) {
+                    name.append(ch);
+                    if (++i < size) {
+                        ch = lower.charAt(i);
+                    } else {
+                        break;
+                    }
+                }
+                i--;
+                buf.append(mapName(name.toString()));
+            } else if (!Character.isWhitespace(ch)) {
+                buf.append(ch);
+            }
+        }
+        return buf.toString();
+    }
+
+
+    /**
+     * @return the matched piece of code as an array of instruction (handles)
+     */
+    private InstructionHandle[] getMatch( int matched_from, int match_length ) {
+        InstructionHandle[] match = new InstructionHandle[match_length];
+        System.arraycopy(handles, matched_from, match, 0, match_length);
+        return match;
+    }
+
+
+    /**
+     * Search for the given pattern in the instruction list. You can search for
+     * any valid opcode via its symbolic name, e.g. "istore". You can also use a
+     * super class or an interface name to match a whole set of instructions, e.g.
+     * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all
+     * "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp"
+     * for "if_icmpxx", "if_acmp" for "if_acmpxx".
+     * 
+     * Consecutive instruction names must be separated by white space which will
+     * be removed during the compilation of the pattern.
+     * 
+     * For the rest the usual pattern matching rules for regular expressions
+     * apply.
+     * <P>
+     * Example pattern:
+     * 
+     * <pre>
+     * search(&quot;BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*&quot;);
+     * </pre>
+     * 
+     * <p>
+     * If you alter the instruction list upon a match such that other matching
+     * areas are affected, you should call reread() to update the finder and call
+     * search() again, because the matches are cached.
+     * 
+     * @param pattern
+     *          the instruction pattern to search for, where case is ignored
+     * @param from
+     *          where to start the search in the instruction list
+     * @param constraint
+     *          optional CodeConstraint to check the found code pattern for
+     *          user-defined constraints
+     * @return iterator of matches where e.nextElement() returns an array of
+     *         instruction handles describing the matched area
+     */
+    public final Iterator search( String pattern, InstructionHandle from, CodeConstraint constraint ) {
+        String search = compilePattern(pattern);
+        int start = -1;
+        for (int i = 0; i < handles.length; i++) {
+            if (handles[i] == from) {
+                start = i; // Where to start search from (index)
+                break;
+            }
+        }
+        if (start == -1) {
+            throw new ClassGenException("Instruction handle " + from
+                    + " not found in instruction list.");
+        }
+        Pattern regex = Pattern.compile(search);
+        List matches = new ArrayList();
+        Matcher matcher = regex.matcher(il_string);
+        while (start < il_string.length() && matcher.find(start)) {
+            int startExpr = matcher.start();
+            int endExpr = matcher.end();
+            int lenExpr = (endExpr - startExpr);
+            InstructionHandle[] match = getMatch(startExpr, lenExpr);
+            if ((constraint == null) || constraint.checkCode(match)) {
+                matches.add(match);
+            }
+            start = endExpr;
+        }
+        return matches.iterator();
+    }
+
+
+    /**
+     * Start search beginning from the start of the given instruction list.
+     * 
+     * @param pattern
+     *          the instruction pattern to search for, where case is ignored
+     * @return iterator of matches where e.nextElement() returns an array of
+     *         instruction handles describing the matched area
+     */
+    public final Iterator search( String pattern ) {
+        return search(pattern, il.getStart(), null);
+    }
+
+
+    /**
+     * Start search beginning from `from'.
+     * 
+     * @param pattern
+     *          the instruction pattern to search for, where case is ignored
+     * @param from
+     *          where to start the search in the instruction list
+     * @return iterator of matches where e.nextElement() returns an array of
+     *         instruction handles describing the matched area
+     */
+    public final Iterator search( String pattern, InstructionHandle from ) {
+        return search(pattern, from, null);
+    }
+
+
+    /**
+     * Start search beginning from the start of the given instruction list. Check
+     * found matches with the constraint object.
+     * 
+     * @param pattern
+     *          the instruction pattern to search for, case is ignored
+     * @param constraint
+     *          constraints to be checked on matching code
+     * @return instruction handle or `null' if the match failed
+     */
+    public final Iterator search( String pattern, CodeConstraint constraint ) {
+        return search(pattern, il.getStart(), constraint);
+    }
+
+
+    /**
+     * Convert opcode number to char.
+     */
+    private static final char makeChar( short opcode ) {
+        return (char) (opcode + OFFSET);
+    }
+
+
+    /**
+     * @return the inquired instruction list
+     */
+    public final InstructionList getInstructionList() {
+        return il;
+    }
+
+    /**
+     * Code patterns found may be checked using an additional user-defined
+     * constraint object whether they really match the needed criterion. I.e.,
+     * check constraints that can not expressed with regular expressions.
+     * 
+     */
+    public static interface CodeConstraint {
+
+        /**
+         * @param match
+         *          array of instructions matching the requested pattern
+         * @return true if the matched area is really useful
+         */
+        public boolean checkCode( InstructionHandle[] match );
+    }
+
+    // Initialize pattern map
+    static {
+        map.put("arithmeticinstruction","(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)");
+               map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)");
+               map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)");
+               map.put("gotoinstruction", "(goto|goto_w)");
+               map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)");
+               map.put("localvariableinstruction","(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)");
+               map.put("loadinstruction", "(fload|dload|lload|iload|aload)");
+               map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)");
+               map.put("cpinstruction", "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)");
+               map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)");
+               map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)");
+               map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)");
+               map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)");
+               map.put("select", "(tableswitch|lookupswitch)");
+               map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)");
+               map.put("jsrinstruction", "(jsr|jsr_w)");
+               map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)");
+               map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)");
+               map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)");
+               map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)");
+               map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)");
+               map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)");
+               map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)");
+               map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)");
+               map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)");
+               map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)");
+               map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)");
+               map.put("loadclass", "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)");
+               map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)");
+               // Some aliases
+               map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)");
+               map.put("if_acmp", "(if_acmpeq|if_acmpne)");
+               map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)");
+               // Precompile some aliases first
+               map.put("iconst", precompile(Constants.ICONST_0, Constants.ICONST_5, Constants.ICONST_M1));
+               map.put("lconst", new String(new char[] { '(', makeChar(Constants.LCONST_0), '|', makeChar(Constants.LCONST_1), ')' }));
+               map.put("dconst", new String(new char[] { '(', makeChar(Constants.DCONST_0), '|', makeChar(Constants.DCONST_1), ')' }));
+               map.put("fconst", new String(new char[] { '(', makeChar(Constants.FCONST_0), '|', makeChar(Constants.FCONST_1), ')' }));
+               map.put("iload", precompile(Constants.ILOAD_0, Constants.ILOAD_3, Constants.ILOAD));
+               map.put("dload", precompile(Constants.DLOAD_0, Constants.DLOAD_3, Constants.DLOAD));
+               map.put("fload", precompile(Constants.FLOAD_0, Constants.FLOAD_3, Constants.FLOAD));
+               map.put("aload", precompile(Constants.ALOAD_0, Constants.ALOAD_3, Constants.ALOAD));
+               map.put("istore", precompile(Constants.ISTORE_0, Constants.ISTORE_3, Constants.ISTORE));
+               map.put("dstore", precompile(Constants.DSTORE_0, Constants.DSTORE_3, Constants.DSTORE));
+               map.put("fstore", precompile(Constants.FSTORE_0, Constants.FSTORE_3, Constants.FSTORE));
+               map.put("astore", precompile(Constants.ASTORE_0, Constants.ASTORE_3, Constants.ASTORE));
+               // Compile strings
+               for (Iterator i = map.keySet().iterator(); i.hasNext();) {
+                       String key = (String) i.next();
+                       String value = (String) map.get(key);
+                       char ch = value.charAt(1); // Omit already precompiled patterns
+                       if (ch < OFFSET) {
+                               map.put(key, compilePattern(value)); // precompile all
+                                                                                                               // patterns
+                       }
+               }
+               // Add instruction alias to match anything
+               StringBuffer buf = new StringBuffer("(");
+               for (short i = 0; i < NO_OPCODES; i++) {
+                       if (Constants.NO_OF_OPERANDS[i] != Constants.UNDEFINED) { // Not
+                                                                                                                                               // an
+                               // invalid
+                               // opcode
+                               buf.append(makeChar(i));
+                               if (i < NO_OPCODES - 1) {
+                                       buf.append('|');
+                               }
+                       }
+               }
+               buf.append(')');
+               map.put("instruction", buf.toString());
+    }
+
+
+    private static String precompile( short from, short to, short extra ) {
+        StringBuffer buf = new StringBuffer("(");
+        for (short i = from; i <= to; i++) {
+            buf.append(makeChar(i));
+            buf.append('|');
+        }
+        buf.append(makeChar(extra));
+        buf.append(")");
+        return buf.toString();
+    }
+
+
+    /*
+        * Internal debugging routines.
+        */
+//    private static final String pattern2string( String pattern ) {
+//        return pattern2string(pattern, true);
+//    }
+
+
+//    private static final String pattern2string( String pattern, boolean make_string ) {
+//        StringBuffer buf = new StringBuffer();
+//        for (int i = 0; i < pattern.length(); i++) {
+//            char ch = pattern.charAt(i);
+//            if (ch >= OFFSET) {
+//                if (make_string) {
+//                    buf.append(Constants.OPCODE_NAMES[ch - OFFSET]);
+//                } else {
+//                    buf.append((ch - OFFSET));
+//                }
+//            } else {
+//                buf.append(ch);
+//            }
+//        }
+//        return buf.toString();
+//    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/JavaWrapper.java b/java/org/apache/tomcat/util/bcel/util/JavaWrapper.java
new file mode 100644 (file)
index 0000000..7b8db45
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Java interpreter replacement, i.e., wrapper that uses its own ClassLoader
+ * to modify/generate classes as they're requested. You can take this as a template
+ * for your own applications.<br>
+ * Call this wrapper with
+ * <pre>java org.apache.tomcat.util.bcel.util.JavaWrapper &lt;real.class.name&gt; [arguments]</pre>
+ * <p>
+ * To use your own class loader you can set the "bcel.classloader" system property
+ * which defaults to "org.apache.tomcat.util.bcel.util.ClassLoader", e.g., with
+ * <pre>java org.apache.tomcat.util.bcel.util.JavaWrapper -Dbcel.classloader=foo.MyLoader &lt;real.class.name&gt; [arguments]</pre>
+ * </p>
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @see ClassLoader
+ */
+public class JavaWrapper {
+
+    private java.lang.ClassLoader loader;
+
+
+    private static java.lang.ClassLoader getClassLoader() {
+        String s = System.getProperty("bcel.classloader");
+        if ((s == null) || "".equals(s)) {
+            s = "org.apache.tomcat.util.bcel.util.ClassLoader";
+        }
+        try {
+            return (java.lang.ClassLoader) Class.forName(s).newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e.toString(), e);
+        }
+    }
+
+
+    public JavaWrapper(java.lang.ClassLoader loader) {
+        this.loader = loader;
+    }
+
+
+    public JavaWrapper() {
+        this(getClassLoader());
+    }
+
+
+    /** Runs the main method of the given class with the arguments passed in argv
+     *
+     * @param class_name the fully qualified class name
+     * @param argv the arguments just as you would pass them directly
+     */
+    public void runMain( String class_name, String[] argv ) throws ClassNotFoundException {
+        Class cl = loader.loadClass(class_name);
+        Method method = null;
+        try {
+            method = cl.getMethod("main", new Class[] {
+                argv.getClass()
+            });
+            /* Method main is sane ?
+             */
+            int m = method.getModifiers();
+            Class r = method.getReturnType();
+            if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m)
+                    || (r != Void.TYPE)) {
+                throw new NoSuchMethodException();
+            }
+        } catch (NoSuchMethodException no) {
+            System.out.println("In class " + class_name
+                    + ": public static void main(String[] argv) is not defined");
+            return;
+        }
+        try {
+            method.invoke(null, new Object[] {
+                argv
+            });
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+
+    /** Default main method used as wrapper, expects the fully qualified class name
+     * of the real class as the first argument.
+     */
+    public static void main( String[] argv ) throws Exception {
+        /* Expects class name as first argument, other arguments are by-passed.
+         */
+        if (argv.length == 0) {
+            System.out.println("Missing class name.");
+            return;
+        }
+        String class_name = argv[0];
+        String[] new_argv = new String[argv.length - 1];
+        System.arraycopy(argv, 1, new_argv, 0, new_argv.length);
+        JavaWrapper wrapper = new JavaWrapper();
+        wrapper.runMain(class_name, new_argv);
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/MethodHTML.java b/java/org/apache/tomcat/util/bcel/util/MethodHTML.java
new file mode 100644 (file)
index 0000000..6aa5118
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import org.apache.tomcat.util.bcel.classfile.Attribute;
+import org.apache.tomcat.util.bcel.classfile.Code;
+import org.apache.tomcat.util.bcel.classfile.ConstantValue;
+import org.apache.tomcat.util.bcel.classfile.ExceptionTable;
+import org.apache.tomcat.util.bcel.classfile.Field;
+import org.apache.tomcat.util.bcel.classfile.Method;
+import org.apache.tomcat.util.bcel.classfile.Utility;
+
+/**
+ * Convert methods and fields into HTML file.
+ *
+ * @version $Id$
+ * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * 
+ */
+final class MethodHTML implements org.apache.tomcat.util.bcel.Constants {
+
+    private String class_name; // name of current class
+    private PrintWriter file; // file to write to
+    private ConstantHTML constant_html;
+    private AttributeHTML attribute_html;
+
+
+    MethodHTML(String dir, String class_name, Method[] methods, Field[] fields,
+            ConstantHTML constant_html, AttributeHTML attribute_html) throws IOException {
+        this.class_name = class_name;
+        this.attribute_html = attribute_html;
+        this.constant_html = constant_html;
+        file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html"));
+        file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>");
+        file.println("<TR><TH ALIGN=LEFT>Access&nbsp;flags</TH><TH ALIGN=LEFT>Type</TH>"
+                + "<TH ALIGN=LEFT>Field&nbsp;name</TH></TR>");
+        for (int i = 0; i < fields.length; i++) {
+            writeField(fields[i]);
+        }
+        file.println("</TABLE>");
+        file.println("<TABLE BORDER=0><TR><TH ALIGN=LEFT>Access&nbsp;flags</TH>"
+                + "<TH ALIGN=LEFT>Return&nbsp;type</TH><TH ALIGN=LEFT>Method&nbsp;name</TH>"
+                + "<TH ALIGN=LEFT>Arguments</TH></TR>");
+        for (int i = 0; i < methods.length; i++) {
+            writeMethod(methods[i], i);
+        }
+        file.println("</TABLE></BODY></HTML>");
+        file.close();
+    }
+
+
+    /**
+     * Print field of class.
+     *
+     * @param field field to print
+     * @exception java.io.IOException
+     */
+    private void writeField( Field field ) throws IOException {
+        String type = Utility.signatureToString(field.getSignature());
+        String name = field.getName();
+        String access = Utility.accessToString(field.getAccessFlags());
+        Attribute[] attributes;
+        access = Utility.replace(access, " ", "&nbsp;");
+        file.print("<TR><TD><FONT COLOR=\"#FF0000\">" + access + "</FONT></TD>\n<TD>"
+                + Class2HTML.referenceType(type) + "</TD><TD><A NAME=\"field" + name + "\">" + name
+                + "</A></TD>");
+        attributes = field.getAttributes();
+        // Write them to the Attributes.html file with anchor "<name>[<i>]"
+        for (int i = 0; i < attributes.length; i++) {
+            attribute_html.writeAttribute(attributes[i], name + "@" + i);
+        }
+        for (int i = 0; i < attributes.length; i++) {
+            if (attributes[i].getTag() == ATTR_CONSTANT_VALUE) { // Default value
+                String str = ((ConstantValue) attributes[i]).toString();
+                // Reference attribute in _attributes.html
+                file.print("<TD>= <A HREF=\"" + class_name + "_attributes.html#" + name + "@" + i
+                        + "\" TARGET=\"Attributes\">" + str + "</TD>\n");
+                break;
+            }
+        }
+        file.println("</TR>");
+    }
+
+
+    private final void writeMethod( Method method, int method_number ) throws IOException {
+        // Get raw signature
+        String signature = method.getSignature();
+        // Get array of strings containing the argument types 
+        String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+        // Get return type string
+        String type = Utility.methodSignatureReturnType(signature, false);
+        // Get method name
+        String name = method.getName(), html_name;
+        // Get method's access flags
+        String access = Utility.accessToString(method.getAccessFlags());
+        // Get the method's attributes, the Code Attribute in particular
+        Attribute[] attributes = method.getAttributes();
+        /* HTML doesn't like names like <clinit> and spaces are places to break
+         * lines. Both we don't want...
+         */
+        access = Utility.replace(access, " ", "&nbsp;");
+        html_name = Class2HTML.toHTML(name);
+        file.print("<TR VALIGN=TOP><TD><FONT COLOR=\"#FF0000\"><A NAME=method" + method_number
+                + ">" + access + "</A></FONT></TD>");
+        file.print("<TD>" + Class2HTML.referenceType(type) + "</TD><TD>" + "<A HREF=" + class_name
+                + "_code.html#method" + method_number + " TARGET=Code>" + html_name
+                + "</A></TD>\n<TD>(");
+        for (int i = 0; i < args.length; i++) {
+            file.print(Class2HTML.referenceType(args[i]));
+            if (i < args.length - 1) {
+                file.print(", ");
+            }
+        }
+        file.print(")</TD></TR>");
+        // Check for thrown exceptions
+        for (int i = 0; i < attributes.length; i++) {
+            attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i,
+                    method_number);
+            byte tag = attributes[i].getTag();
+            if (tag == ATTR_EXCEPTIONS) {
+                file.print("<TR VALIGN=TOP><TD COLSPAN=2></TD><TH ALIGN=LEFT>throws</TH><TD>");
+                int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable();
+                for (int j = 0; j < exceptions.length; j++) {
+                    file.print(constant_html.referenceConstant(exceptions[j]));
+                    if (j < exceptions.length - 1) {
+                        file.print(", ");
+                    }
+                }
+                file.println("</TD></TR>");
+            } else if (tag == ATTR_CODE) {
+                Attribute[] c_a = ((Code) attributes[i]).getAttributes();
+                for (int j = 0; j < c_a.length; j++) {
+                    attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@"
+                            + j, method_number);
+                }
+            }
+        }
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/Repository.java b/java/org/apache/tomcat/util/bcel/util/Repository.java
new file mode 100644 (file)
index 0000000..47484ee
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/**
+ * Abstract definition of a class repository. Instances may be used
+ * to load classes from different sources and may be used in the
+ * Repository.setRepository method.
+ *
+ * @see org.apache.tomcat.util.bcel.Repository
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public interface Repository extends java.io.Serializable {
+
+    /**
+     * Store the provided class under "clazz.getClassName()" 
+     */
+    public void storeClass( JavaClass clazz );
+
+
+    /**
+     * Remove class from repository
+     */
+    public void removeClass( JavaClass clazz );
+
+
+    /**
+     * Find the class with the name provided, if the class
+     * isn't there, return NULL.
+     */
+    public JavaClass findClass( String className );
+
+
+    /**
+     * Find the class with the name provided, if the class
+     * isn't there, make an attempt to load it.
+     */
+    public JavaClass loadClass( String className ) throws java.lang.ClassNotFoundException;
+
+
+    /**
+     * Find the JavaClass instance for the given run-time class object
+     */
+    public JavaClass loadClass( Class clazz ) throws java.lang.ClassNotFoundException;
+
+
+    /** Clear all entries from cache.
+     */
+    public void clear();
+
+
+    /** Get the ClassPath associated with this Repository
+     */
+    public ClassPath getClassPath();
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/SyntheticRepository.java b/java/org/apache/tomcat/util/bcel/util/SyntheticRepository.java
new file mode 100644 (file)
index 0000000..336e5a9
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright  2000-2009 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.tomcat.util.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.tomcat.util.bcel.classfile.ClassParser;
+import org.apache.tomcat.util.bcel.classfile.JavaClass;
+
+/**
+ * This repository is used in situations where a Class is created
+ * outside the realm of a ClassLoader. Classes are loaded from
+ * the file systems using the paths specified in the given
+ * class path. By default, this is the value returned by
+ * ClassPath.getClassPath().
+ * <br>
+ * It is designed to be used as a singleton, however it
+ * can also be used with custom classpaths.
+ *
+ /**
+ * Abstract definition of a class repository. Instances may be used
+ * to load classes from different sources and may be used in the
+ * Repository.setRepository method.
+ *
+ * @see org.apache.tomcat.util.bcel.Repository
+ *
+ * @version $Id$
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
+ * @author David Dixon-Peugh
+ */
+public class SyntheticRepository implements Repository {
+
+    //private static final String DEFAULT_PATH = ClassPath.getClassPath();
+    private static Map _instances = new HashMap(); // CLASSPATH X REPOSITORY
+    private ClassPath _path = null;
+    private Map _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS
+
+
+    private SyntheticRepository(ClassPath path) {
+        _path = path;
+    }
+
+
+    public static SyntheticRepository getInstance() {
+        return getInstance(ClassPath.SYSTEM_CLASS_PATH);
+    }
+
+
+    public static SyntheticRepository getInstance( ClassPath classPath ) {
+        SyntheticRepository rep = (SyntheticRepository) _instances.get(classPath);
+        if (rep == null) {
+            rep = new SyntheticRepository(classPath);
+            _instances.put(classPath, rep);
+        }
+        return rep;
+    }
+
+
+    /**
+     * Store a new JavaClass instance into this Repository.
+     */
+    public void storeClass( JavaClass clazz ) {
+        _loadedClasses.put(clazz.getClassName(), new SoftReference(clazz));
+        clazz.setRepository(this);
+    }
+
+
+    /**
+     * Remove class from repository
+     */
+    public void removeClass( JavaClass clazz ) {
+        _loadedClasses.remove(clazz.getClassName());
+    }
+
+
+    /**
+     * Find an already defined (cached) JavaClass object by name.
+     */
+    public JavaClass findClass( String className ) {
+        SoftReference ref = (SoftReference) _loadedClasses.get(className);
+        if (ref == null) {
+            return null;
+        }
+        return (JavaClass) ref.get();
+    }
+
+
+    /**
+     * Find a JavaClass object by name.
+     * If it is already in this Repository, the Repository version
+     * is returned.  Otherwise, the Repository's classpath is searched for
+     * the class (and it is added to the Repository if found).
+     *
+     * @param className the name of the class
+     * @return the JavaClass object
+     * @throws ClassNotFoundException if the class is not in the
+     *   Repository, and could not be found on the classpath
+     */
+    public JavaClass loadClass( String className ) throws ClassNotFoundException {
+        if (className == null || className.equals("")) {
+            throw new IllegalArgumentException("Invalid class name " + className);
+        }
+        className = className.replace('/', '.'); // Just in case, canonical form
+        JavaClass clazz = findClass(className);
+        if (clazz != null) {
+            return clazz;
+        }
+        try {
+            return loadClass(_path.getInputStream(className), className);
+        } catch (IOException e) {
+            throw new ClassNotFoundException("Exception while looking for class " + className
+                    + ": " + e.toString(), e);
+        }
+    }
+
+
+    /**
+     * Find the JavaClass object for a runtime Class object.
+     * If a class with the same name is already in this Repository,
+     * the Repository version is returned.  Otherwise, getResourceAsStream()
+     * is called on the Class object to find the class's representation.
+     * If the representation is found, it is added to the Repository.
+     *
+     * @see Class
+     * @param clazz the runtime Class object
+     * @return JavaClass object for given runtime class
+     * @throws ClassNotFoundException if the class is not in the
+     *   Repository, and its representation could not be found
+     */
+    public JavaClass loadClass( Class clazz ) throws ClassNotFoundException {
+       InputStream clsStream = null;
+       try{
+               String className = clazz.getName();
+               JavaClass repositoryClass = findClass(className);
+               if (repositoryClass != null) {
+                   return repositoryClass;
+               }
+               String name = className;
+               int i = name.lastIndexOf('.');
+               if (i > 0) {
+                   name = name.substring(i + 1);
+               }
+               clsStream = clazz.getResourceAsStream(name + ".class");
+               return loadClass(clsStream, className);
+       } finally {
+               try{
+                       if (clsStream != null){
+                               clsStream.close();
+                       }
+               } catch(IOException ioe){
+                       //don't care
+               }
+       }
+    }
+
+
+    private JavaClass loadClass( InputStream is, String className ) throws ClassNotFoundException {
+        try {
+            if (is != null) {
+                ClassParser parser = new ClassParser(is, className);
+                JavaClass clazz = parser.parse();
+                storeClass(clazz);
+                return clazz;
+            }
+        } catch (IOException e) {
+            throw new ClassNotFoundException("Exception while looking for class " + className
+                    + ": " + e.toString(), e);
+        }
+        throw new ClassNotFoundException("SyntheticRepository could not load " + className);
+    }
+
+
+    /** ClassPath associated with the Repository.
+     */
+    public ClassPath getClassPath() {
+        return _path;
+    }
+
+
+    /** Clear all entries from cache.
+     */
+    public void clear() {
+        _loadedClasses.clear();
+    }
+}
diff --git a/java/org/apache/tomcat/util/bcel/util/package.html b/java/org/apache/tomcat/util/bcel/util/package.html
new file mode 100644 (file)
index 0000000..abef411
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+$Id$
+-->
+</head>
+<body bgcolor="white">
+<p>
+This package contains utility classes for the
+<a href="http://jakarta.apache.org/bcel/">Byte Code Engineering
+Library</a>, namely:
+</p>
+<p>
+<ul>
+<li>Collection classes for JavaClass objects</li>
+<li>A converter for class files to HTML</li>
+<li>A tool to find instructions patterns via regular expressions</li>
+<li>A class to find classes as defined in the CLASSPATH</li>
+<li>A class loader that allows to create classes at run time</li>
+</ul>
+
+</p>
+</body>
+</html>