Clean up apache BCEL lib, no more stupid warnings

This commit is contained in:
Shevchik
2013-12-15 15:26:10 +04:00
parent 6548caeddb
commit 4f00ab70b1
275 changed files with 26436 additions and 24293 deletions

View File

@@ -19,220 +19,194 @@ package org.apache.bcel.classfile;
import org.apache.bcel.Constants;
/**
* Super class for all objects that have modifiers like private, final, ...
* I.e. classes, fields, and methods.
*
* Super class for all objects that have modifiers like private, final, ... I.e.
* classes, fields, and methods.
*
* @version $Id: AccessFlags.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public abstract class AccessFlags implements java.io.Serializable {
protected int access_flags;
/**
*
*/
private static final long serialVersionUID = 1L;
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 AccessFlags() {
}
public final void isAnnotation(boolean flag) {
setFlag(Constants.ACC_ANNOTATION, flag);
}
public final boolean isAnnotation() {
return (access_flags & Constants.ACC_ANNOTATION) != 0;
}
/**
* @param a inital access flags
*/
public AccessFlags(int a) {
access_flags = a;
}
public final void isEnum(boolean flag) {
setFlag(Constants.ACC_ENUM, flag);
}
/**
* @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;
}
public final boolean isEnum() {
return (access_flags & Constants.ACC_ENUM) != 0;
}
}

View File

@@ -22,257 +22,276 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.bcel.Constants;
/**
* 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.
*
* <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: Attribute.java 386056 2006-03-15 11:31:56Z tcurdt $
* @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
* @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;
/**
*
*/
private static final long serialVersionUID = 1L;
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;
}
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
*/
@Override
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);
}
/**
* 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 );
private static Map<String, AttributeReader> readers = new HashMap<String, AttributeReader>();
/**
* 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);
}
/**
* 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);
}
/**
* 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);
}
private static Map readers = new HashMap();
/*
* 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
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 = 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_RUNTIMEVISIBLE_ANNOTATIONS:
// return new RuntimeVisibleAnnotations(name_index, length, file,
// constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS:
// return new RuntimeInvisibleAnnotations(name_index, length, file,
// constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeVisibleParameterAnnotations(name_index, length,
// file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_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);
default: // Never reached
throw new IllegalStateException("Ooops! default case reached.");
}
}
/**
* @return Length of attribute field in bytes.
*/
public final int getLength() {
return length;
}
/** 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);
}
/**
* @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;
}
/** 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);
}
/**
* @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;
}
/* 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
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_RUNTIMEVISIBLE_ANNOTATIONS:
// return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS:
// return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_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);
default: // Never reached
throw new IllegalStateException("Ooops! default case reached.");
}
}
/**
* @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;
}
/**
* @return Length of attribute field in bytes.
*/
public final int getLength() {
return length;
}
/**
* Use copy() if you want to have a deep copy(), i.e., with all references
* copied correctly.
*
* @return shallow copy of this attribute
*/
@Override
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);
/**
* @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];
}
/**
* @return attribute name.
*/
@Override
public String toString() {
return Constants.ATTRIBUTE_NAMES[tag];
}
}

View File

@@ -18,41 +18,39 @@ package org.apache.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.
* objects that can be registered with the Attribute.addAttributeReader method.
* These factory objects should implement this interface.
*
* @see Attribute
* @version $Id: AttributeReader.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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 );
/**
* 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);
}

View File

@@ -16,22 +16,25 @@
*/
package org.apache.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.
*
/**
* 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: ClassFormatException.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public class ClassFormatException extends RuntimeException {
public ClassFormatException() {
super();
}
/**
*
*/
private static final long serialVersionUID = 1L;
public ClassFormatException() {
super();
}
public ClassFormatException(String s) {
super(s);
}
public ClassFormatException(String s) {
super(s);
}
}

View File

@@ -26,270 +26,283 @@ import java.util.zip.ZipFile;
import org.apache.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.
*
* 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: ClassParser.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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;
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 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) throws IOException {
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 class from given .class file.
*
* @param file_name file name
*/
public ClassParser(String file_name) throws IOException {
is_zip = false;
this.file_name = file_name;
fileOwned = true;
}
/**
* 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) {
file.close();
if (zip != null) {
zip.close();
}
}
}
// 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);
}
}
/** 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;
}
/**
* 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 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);
}
/**
* 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) {
file.close();
if (zip != null) {
zip.close();
}
}
}
// 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 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 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 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 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 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();
}
/**
* 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();
}
}

View File

@@ -21,332 +21,351 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.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 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.
*
* is used for debugging purposes and <em>LocalVariableTable</em> which contains
* information about the local variables.
*
* @version $Id: Code.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @see CodeException
* @see LineNumberTable
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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!
}
/**
* @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;
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitCode(this);
}
/**
* Dump code attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
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);
}
}
/**
* @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!
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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 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 Collection of code attributes.
* @see Attribute
*/
public final Attribute[] getAttributes() {
return attributes;
}
/**
* @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 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 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
}
/**
* @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;
}
/**
* @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;
}
/**
* @return Actual byte code of the method.
*/
public final byte[] getCode() {
return code;
}
/**
* @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 Table of handled exceptions.
* @see CodeException
*/
public final CodeException[] getExceptionTable() {
return exception_table;
}
/**
* @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.
*/
@Override
public final String toString() {
return toString(true);
}
/**
* @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;
}
/**
* @return deep copy of this attribute
*
* @param _constant_pool
* the constant pool to duplicate
*/
@Override
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;
}
}

View File

@@ -24,191 +24,197 @@ import org.apache.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.
*
* attribute and is used only there. It contains a range in which a particular
* exception handler is active.
*
* @version $Id: CodeException.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
*/
public final class CodeException implements Cloneable, Constants, Node, Serializable {
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.
*/
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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(DataInputStream 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;
}
/**
* Construct object from file stream.
* @param file Input stream
* @throws IOException
*/
CodeException(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), 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
*/
@Override
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);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* @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;
}
/**
* @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 Exclusive end index of the region where the handler is active.
*/
public final int getEndPC() {
return end_pc;
}
/**
* @return String representation.
*/
@Override
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;
}
/**
* @return Starting address of exception handler, relative to the code.
*/
public final int getHandlerPC() {
return handler_pc;
}
public final String toString(ConstantPool cp) {
return toString(cp, true);
}
/**
* @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;
}
/**
* @return deep copy of this object
*/
public CodeException copy() {
try {
return (CodeException) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
}

View File

@@ -24,165 +24,168 @@ import org.apache.bcel.Constants;
import org.apache.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.
*
* 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: Constant.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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() {
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
@Override
public boolean equals(Object o1, Object o2) {
Constant THIS = (Constant) o1;
Constant THAT = (Constant) o2;
return THIS.toString().equals(THAT.toString());
}
@Override
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;
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
*/
@Override
public abstract void accept(Visitor v);
Constant(byte tag) {
this.tag = tag;
}
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;
}
/**
* 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 );
/**
* @return String representation.
*/
@Override
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 abstract void dump( DataOutputStream file ) throws IOException;
@Override
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 Tag of constant, i.e., its type. No setTag() method to avoid
* confusion.
*/
public final byte getTag() {
return tag;
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @param comparator
* Comparison strategy object
*/
public static void setComparator(BCELComparator comparator) {
_cmp = comparator;
}
/**
* @return String representation.
*/
public String toString() {
return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
}
/**
* 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)
*/
@Override
public boolean equals(Object obj) {
return _cmp.equals(this, obj);
}
/**
* @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);
}
/**
* Return value as defined by given BCELComparator strategy. By default
* return the hashcode of the result of toString().
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return _cmp.hashCode(this);
}
}

View File

@@ -21,111 +21,115 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
/**
* Abstract super class for Fieldref and Methodref constants.
*
*
* @version $Id: ConstantCP.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see ConstantFieldref
* @see ConstantMethodref
* @see ConstantInterfaceMethodref
* @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;
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 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 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, DataInputStream 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;
}
/**
* Initialize instance from file data.
*
* @param tag Constant type tag
* @param file Input stream
* @throws IOException
*/
ConstantCP(byte tag, DataInputStream file) throws IOException {
this(tag, file.readUnsignedShort(), file.readUnsignedShort());
}
/**
* Dump constant field reference to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
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;
}
/**
* @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;
}
/**
* @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;
}
/**
* 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 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 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 + ")";
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(class_index = " + class_index
+ ", name_and_type_index = " + name_and_type_index + ")";
}
}

View File

@@ -21,108 +21,112 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a (external) class.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a (external) class.
*
* @version $Id: ConstantClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
private int name_index; // Identical to ConstantString except for the name
/**
* Initialize from another object.
*/
public ConstantClass(ConstantClass c) {
this(c.getNameIndex());
}
/**
* Initialize from another object.
*/
public ConstantClass(ConstantClass c) {
this(c.getNameIndex());
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantClass(DataInputStream 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;
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantClass(DataInputStream file) throws IOException {
this(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
*/
@Override
public void accept(Visitor v) {
v.visitConstantClass(this);
}
/**
* Dump constant class to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(name_index);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String object
*/
@Override
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);
}
/**
* 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 + ")";
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(name_index = " + name_index + ")";
}
}

View File

@@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a Double object.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a Double object.
*
* @version $Id: ConstantDouble.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
*/
public final class ConstantDouble extends Constant implements ConstantObject {
private double bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
private double bytes;
/**
* @param bytes
* Data
*/
public ConstantDouble(double bytes) {
super(Constants.CONSTANT_Double);
this.bytes = 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(DataInputStream file) throws IOException {
this(file.readDouble());
}
/**
* Initialize from another object.
*/
public ConstantDouble(ConstantDouble c) {
this(c.getBytes());
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantDouble(this);
}
/**
* Dump constant double to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeDouble(bytes);
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantDouble(DataInputStream file) throws IOException {
this(file.readDouble());
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/**
* 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);
}
/**
* @return Double object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
return new Double(bytes);
}
}

View File

@@ -20,50 +20,58 @@ import java.io.DataInputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
/**
* This class represents a constant pool reference to a field.
*
*
* @version $Id: ConstantFieldref.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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());
}
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 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);
}
/**
* 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);
}
/**
* @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);
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantFieldref(this);
}
}

View File

@@ -21,100 +21,105 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a float object.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a float object.
*
* @version $Id: ConstantFloat.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
*/
public final class ConstantFloat extends Constant implements ConstantObject {
private float bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
private float bytes;
/**
* @param bytes
* Data
*/
public ConstantFloat(float bytes) {
super(Constants.CONSTANT_Float);
this.bytes = 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(DataInputStream file) throws IOException {
this(file.readFloat());
}
/**
* 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());
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantFloat(this);
}
/**
* Dump constant float to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeFloat(bytes);
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantFloat(DataInputStream file) throws IOException {
this(file.readFloat());
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/**
* 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);
}
/**
* @return Float object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
return new Float(bytes);
}
}

View File

@@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to an int object.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to an int object.
*
* @version $Id: ConstantInteger.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
*/
public final class ConstantInteger extends Constant implements ConstantObject {
private int bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
private int bytes;
/**
* @param bytes
* Data
*/
public ConstantInteger(int bytes) {
super(Constants.CONSTANT_Integer);
this.bytes = 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(DataInputStream file) throws IOException {
this(file.readInt());
}
/**
* Initialize from another object.
*/
public ConstantInteger(ConstantInteger c) {
this(c.getBytes());
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantInteger(this);
}
/**
* Dump constant integer to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeInt(bytes);
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantInteger(DataInputStream file) throws IOException {
this(file.readInt());
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/**
* 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);
}
/**
* @return Integer object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
return new Integer(bytes);
}
}

View File

@@ -20,50 +20,60 @@ import java.io.DataInputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
/**
* This class represents a constant pool reference to an interface method.
*
* @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*
* @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z
* tcurdt $
* @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());
}
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 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);
}
/**
* 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);
}
/**
* @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);
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantInterfaceMethodref(this);
}
}

View File

@@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a long object.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a long object.
*
* @version $Id: ConstantLong.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
*/
public final class ConstantLong extends Constant implements ConstantObject {
private long bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
private long bytes;
/**
* @param bytes
* Data
*/
public ConstantLong(long bytes) {
super(Constants.CONSTANT_Long);
this.bytes = 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(DataInputStream file) throws IOException {
this(file.readLong());
}
/**
* Initialize from another object.
*/
public ConstantLong(ConstantLong c) {
this(c.getBytes());
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantLong(this);
}
/**
* Dump constant long to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeLong(bytes);
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantLong(DataInputStream file) throws IOException {
this(file.readLong());
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/**
* 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);
}
/**
* @return Long object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
return new Long(bytes);
}
}

View File

@@ -20,50 +20,58 @@ import java.io.DataInputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
/**
* This class represents a constant pool reference to a method.
*
*
* @version $Id: ConstantMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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());
}
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 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);
}
/**
* 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);
}
/**
* @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);
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantMethodref(this);
}
}

View File

@@ -21,128 +21,132 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to the name and signature
* of a field or method.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to the name and signature of a field or method.
*
* @version $Id: ConstantNameAndType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @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.
/**
*
*/
private static final long serialVersionUID = 1L;
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 from another object.
*/
public ConstantNameAndType(ConstantNameAndType c) {
this(c.getNameIndex(), c.getSignatureIndex());
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantNameAndType(DataInputStream 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;
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantNameAndType(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(name_index);
file.writeShort(signature_index);
}
/**
* @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;
}
/**
* @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);
}
/**
* 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);
}
/**
* @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);
}
/**
* 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);
}
/**
* @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 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 + ")";
}
/**
* @return String representation
*/
@Override
public final String toString() {
return super.toString() + "(name_index = " + name_index
+ ", signature_index = " + signature_index + ")";
}
}

View File

@@ -16,17 +16,18 @@
*/
package org.apache.bcel.classfile;
/**
* This interface denotes those constants that have a "natural" value,
* such as ConstantLong, ConstantString, etc..
*
/**
* This interface denotes those constants that have a "natural" value, such as
* ConstantLong, ConstantString, etc..
*
* @version $Id: ConstantObject.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @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 );
/**
* @return object representing the constant, e.g., Long for ConstantLong
*/
public abstract Object getConstantValue(ConstantPool cp);
}

View File

@@ -23,331 +23,346 @@ import java.io.Serializable;
import org.apache.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>.
* 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: ConstantPool.java 386056 2006-03-15 11:31:56Z tcurdt $
* @see Constant
* @see org.apache.bcel.generic.ConstantPoolGen
* @see Constant
* @see org.apache.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;
/**
*
*/
private static final long serialVersionUID = 1L;
private int constant_pool_count;
private Constant[] constant_pool;
/**
* @param constant_pool
* Array of constants
*/
public ConstantPool(Constant[] constant_pool) {
setConstantPool(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
*/
@Override
public void accept(Visitor v) {
v.visitConstantPool(this);
}
/**
* 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++;
}
}
}
/**
* 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 = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Float:
str = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Long:
str = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Integer:
str = "" + ((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();
}
/**
* 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);
}
/**
* 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);
}
}
}
/**
* 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 = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Float:
str = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Long:
str = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Integer:
str = "" + ((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;
}
/**
* 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;
}
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();
}
/**
* @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();
}
/**
* 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);
}
/**
* @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;
}
/**
* 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);
}
}
}
/**
* @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.
*/
@Override
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();
}
/**
* 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;
}
/**
* @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;
}
}

View File

@@ -21,107 +21,112 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a String object.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a String object.
*
* @version $Id: ConstantString.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
private int string_index; // Identical to ConstantClass except for this name
/**
* Initialize from another object.
*/
public ConstantString(ConstantString c) {
this(c.getStringIndex());
}
/**
* Initialize from another object.
*/
public ConstantString(ConstantString c) {
this(c.getStringIndex());
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantString(DataInputStream 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;
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantString(DataInputStream file) throws IOException {
this(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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(string_index);
}
/**
* @param string_index Index of Constant_Utf8 in constant pool
*/
public ConstantString(int string_index) {
super(Constants.CONSTANT_String);
this.string_index = 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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
return super.toString() + "(string_index = " + string_index + ")";
}
/**
* @return String object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/**
* 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);
}
/**
* @return dereferenced string
*/
public String getBytes(ConstantPool cp) {
return (String) getConstantValue(cp);
}
}

View File

@@ -21,96 +21,101 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from the abstract
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class
* and represents a reference to a Utf8 encoded string.
*
/**
* This class is derived from the abstract <A
* HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* represents a reference to a Utf8 encoded string.
*
* @version $Id: ConstantUtf8.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant
*/
public final class ConstantUtf8 extends Constant {
private String bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
private String bytes;
/**
* Initialize from another object.
*/
public ConstantUtf8(ConstantUtf8 c) {
this(c.getBytes());
}
/**
* Initialize from another object.
*/
public ConstantUtf8(ConstantUtf8 c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantUtf8(DataInputStream 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;
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throws IOException
*/
ConstantUtf8(DataInputStream file) throws IOException {
super(Constants.CONSTANT_Utf8);
bytes = file.readUTF();
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitConstantUtf8(this);
}
/**
* Dump String in Utf8 format to file stream.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeUTF(bytes);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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") + "\")";
}
/**
* @return String representation
*/
@Override
public final String toString() {
return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n")
+ "\")";
}
}

View File

@@ -22,134 +22,147 @@ import java.io.IOException;
import org.apache.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.
*
* 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: ConstantValue.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
*/
public final class ConstantValue extends Attribute {
private int constantvalue_index;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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, DataInputStream 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;
}
/**
* 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, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, file.readUnsignedShort(), 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(constantvalue_index);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation of constant value.
*/
@Override
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 = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Float:
buf = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Double:
buf = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Integer:
buf = "" + ((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;
}
/**
* 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 = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Float:
buf = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Double:
buf = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Integer:
buf = "" + ((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;
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
ConstantValue c = (ConstantValue) clone();
c.constant_pool = _constant_pool;
return c;
}
}

View File

@@ -23,118 +23,130 @@ import org.apache.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.
*
* deprecated method. It is instantiated from the
* <em>Attribute.readAttribute()</em> method.
*
* @version $Id: Deprecated.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
*/
public final class Deprecated extends Attribute {
private byte[] bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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");
}
}
/**
* @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;
}
/**
* 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
if (length > 0) {
file.write(bytes, 0, length);
}
}
/**
* 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");
}
}
/**
* @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;
}
/**
* 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);
}
/**
* @return attribute name
*/
@Override
public final String toString() {
return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED];
}
/**
* 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;
}
/**
* @return deep copy of this attribute
*/
@Override
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;
}
}

View File

@@ -19,338 +19,338 @@ package org.apache.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.
*
* Traverses a JavaClass with another Visitor object 'piggy-backed' that is
* applied to all components of a JavaClass object. I.e. this class supplies the
* traversal strategy, other classes can make use of it.
*
* @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public class DescendingVisitor implements Visitor {
private JavaClass clazz;
private Visitor visitor;
private Stack stack = new Stack();
/** @return container of current entitity, i.e., predecessor during traversal
*/
public Object predecessor() {
return predecessor(0);
}
/**
* @param level nesting level, i.e., 0 returns the direct predecessor
* @return container of current entitity, i.e., predecessor during traversal
*/
public Object predecessor( int level ) {
int size = stack.size();
if ((size < 2) || (level < 0)) {
return null;
} else {
return stack.elementAt(size - (level + 2)); // size - 1 == current
}
}
/** @return current object
*/
public Object current() {
return stack.peek();
}
/**
* @param clazz Class to traverse
* @param visitor visitor object to apply to all components
*/
public DescendingVisitor(JavaClass clazz, Visitor visitor) {
this.clazz = clazz;
this.visitor = visitor;
}
/**
* Start traversal.
*/
public void visit() {
clazz.accept(this);
}
public void visitJavaClass( JavaClass _clazz ) {
stack.push(_clazz);
_clazz.accept(visitor);
Field[] fields = _clazz.getFields();
for (int i = 0; i < fields.length; i++) {
fields[i].accept(this);
}
Method[] methods = _clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
methods[i].accept(this);
}
Attribute[] attributes = _clazz.getAttributes();
for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this);
}
_clazz.getConstantPool().accept(this);
stack.pop();
}
public void visitField( Field field ) {
stack.push(field);
field.accept(visitor);
Attribute[] attributes = field.getAttributes();
for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this);
}
stack.pop();
}
public void visitConstantValue( ConstantValue cv ) {
stack.push(cv);
cv.accept(visitor);
stack.pop();
}
public void visitMethod( Method method ) {
stack.push(method);
method.accept(visitor);
Attribute[] attributes = method.getAttributes();
for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this);
}
stack.pop();
}
public void visitExceptionTable( ExceptionTable table ) {
stack.push(table);
table.accept(visitor);
stack.pop();
}
public void visitCode( Code code ) {
stack.push(code);
code.accept(visitor);
CodeException[] table = code.getExceptionTable();
for (int i = 0; i < table.length; i++) {
table[i].accept(this);
}
Attribute[] attributes = code.getAttributes();
for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this);
}
stack.pop();
}
public void visitCodeException( CodeException ce ) {
stack.push(ce);
ce.accept(visitor);
stack.pop();
}
public void visitLineNumberTable( LineNumberTable table ) {
stack.push(table);
table.accept(visitor);
LineNumber[] numbers = table.getLineNumberTable();
for (int i = 0; i < numbers.length; i++) {
numbers[i].accept(this);
}
stack.pop();
}
public void visitLineNumber( LineNumber number ) {
stack.push(number);
number.accept(visitor);
stack.pop();
}
public void visitLocalVariableTable( LocalVariableTable table ) {
stack.push(table);
table.accept(visitor);
LocalVariable[] vars = table.getLocalVariableTable();
for (int i = 0; i < vars.length; i++) {
vars[i].accept(this);
}
stack.pop();
}
public void visitStackMap( StackMap table ) {
stack.push(table);
table.accept(visitor);
StackMapEntry[] vars = table.getStackMap();
for (int i = 0; i < vars.length; i++) {
vars[i].accept(this);
}
stack.pop();
}
public void visitStackMapEntry( StackMapEntry var ) {
stack.push(var);
var.accept(visitor);
stack.pop();
}
public void visitLocalVariable( LocalVariable var ) {
stack.push(var);
var.accept(visitor);
stack.pop();
}
public void visitConstantPool( ConstantPool cp ) {
stack.push(cp);
cp.accept(visitor);
Constant[] constants = cp.getConstantPool();
for (int i = 1; i < constants.length; i++) {
if (constants[i] != null) {
constants[i].accept(this);
}
}
stack.pop();
}
public void visitConstantClass( ConstantClass constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantDouble( ConstantDouble constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantFieldref( ConstantFieldref constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantFloat( ConstantFloat constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantInteger( ConstantInteger constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantLong( ConstantLong constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantMethodref( ConstantMethodref constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantNameAndType( ConstantNameAndType constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantString( ConstantString constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitConstantUtf8( ConstantUtf8 constant ) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
public void visitInnerClasses( InnerClasses ic ) {
stack.push(ic);
ic.accept(visitor);
InnerClass[] ics = ic.getInnerClasses();
for (int i = 0; i < ics.length; i++) {
ics[i].accept(this);
}
stack.pop();
}
public void visitInnerClass( InnerClass inner ) {
stack.push(inner);
inner.accept(visitor);
stack.pop();
}
public void visitDeprecated( Deprecated attribute ) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
public void visitSignature( Signature attribute ) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
public void visitSourceFile( SourceFile attribute ) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
public void visitSynthetic( Synthetic attribute ) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
public void visitUnknown( Unknown attribute ) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
private JavaClass clazz;
private Visitor visitor;
private Stack<Cloneable> stack = new Stack<Cloneable>();
/**
* @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);
}
@Override
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();
}
@Override
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();
}
@Override
public void visitConstantValue(ConstantValue cv) {
stack.push(cv);
cv.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
public void visitExceptionTable(ExceptionTable table) {
stack.push(table);
table.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
public void visitCodeException(CodeException ce) {
stack.push(ce);
ce.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
public void visitLineNumber(LineNumber number) {
stack.push(number);
number.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
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();
}
@Override
public void visitStackMapEntry(StackMapEntry var) {
stack.push(var);
var.accept(visitor);
stack.pop();
}
@Override
public void visitLocalVariable(LocalVariable var) {
stack.push(var);
var.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
public void visitConstantClass(ConstantClass constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantDouble(ConstantDouble constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantFieldref(ConstantFieldref constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantFloat(ConstantFloat constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantInteger(ConstantInteger constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantInterfaceMethodref(
ConstantInterfaceMethodref constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantLong(ConstantLong constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantMethodref(ConstantMethodref constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantNameAndType(ConstantNameAndType constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantString(ConstantString constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
public void visitConstantUtf8(ConstantUtf8 constant) {
stack.push(constant);
constant.accept(visitor);
stack.pop();
}
@Override
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();
}
@Override
public void visitInnerClass(InnerClass inner) {
stack.push(inner);
inner.accept(visitor);
stack.pop();
}
@Override
public void visitDeprecated(Deprecated attribute) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
@Override
public void visitSignature(Signature attribute) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
@Override
public void visitSourceFile(SourceFile attribute) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
@Override
public void visitSynthetic(Synthetic attribute) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
@Override
public void visitUnknown(Unknown attribute) {
stack.push(attribute);
attribute.accept(visitor);
stack.pop();
}
}

View File

@@ -17,145 +17,145 @@
package org.apache.bcel.classfile;
/**
* Visitor with empty method bodies, can be extended and used in conjunction with the
* DescendingVisitor class, e.g.
*
* 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: EmptyVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $
*
*/
public class EmptyVisitor implements Visitor {
protected EmptyVisitor() {
}
protected EmptyVisitor() {
}
@Override
public void visitCode(Code obj) {
}
public void visitCode( Code obj ) {
}
@Override
public void visitCodeException(CodeException obj) {
}
@Override
public void visitConstantClass(ConstantClass obj) {
}
public void visitCodeException( CodeException obj ) {
}
@Override
public void visitConstantDouble(ConstantDouble obj) {
}
@Override
public void visitConstantFieldref(ConstantFieldref obj) {
}
public void visitConstantClass( ConstantClass obj ) {
}
@Override
public void visitConstantFloat(ConstantFloat obj) {
}
@Override
public void visitConstantInteger(ConstantInteger obj) {
}
public void visitConstantDouble( ConstantDouble obj ) {
}
@Override
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) {
}
@Override
public void visitConstantLong(ConstantLong obj) {
}
public void visitConstantFieldref( ConstantFieldref obj ) {
}
@Override
public void visitConstantMethodref(ConstantMethodref obj) {
}
@Override
public void visitConstantNameAndType(ConstantNameAndType obj) {
}
public void visitConstantFloat( ConstantFloat obj ) {
}
@Override
public void visitConstantPool(ConstantPool obj) {
}
@Override
public void visitConstantString(ConstantString obj) {
}
public void visitConstantInteger( ConstantInteger obj ) {
}
@Override
public void visitConstantUtf8(ConstantUtf8 obj) {
}
@Override
public void visitConstantValue(ConstantValue obj) {
}
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj ) {
}
@Override
public void visitDeprecated(Deprecated obj) {
}
@Override
public void visitExceptionTable(ExceptionTable obj) {
}
public void visitConstantLong( ConstantLong obj ) {
}
@Override
public void visitField(Field obj) {
}
@Override
public void visitInnerClass(InnerClass obj) {
}
public void visitConstantMethodref( ConstantMethodref obj ) {
}
@Override
public void visitInnerClasses(InnerClasses obj) {
}
@Override
public void visitJavaClass(JavaClass obj) {
}
public void visitConstantNameAndType( ConstantNameAndType obj ) {
}
@Override
public void visitLineNumber(LineNumber obj) {
}
@Override
public void visitLineNumberTable(LineNumberTable obj) {
}
public void visitConstantPool( ConstantPool obj ) {
}
@Override
public void visitLocalVariable(LocalVariable obj) {
}
@Override
public void visitLocalVariableTable(LocalVariableTable obj) {
}
public void visitConstantString( ConstantString obj ) {
}
@Override
public void visitMethod(Method obj) {
}
@Override
public void visitSignature(Signature obj) {
}
public void visitConstantUtf8( ConstantUtf8 obj ) {
}
@Override
public void visitSourceFile(SourceFile obj) {
}
@Override
public void visitSynthetic(Synthetic obj) {
}
public void visitConstantValue( ConstantValue obj ) {
}
@Override
public void visitUnknown(Unknown obj) {
}
@Override
public void visitStackMap(StackMap 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 ) {
}
@Override
public void visitStackMapEntry(StackMapEntry obj) {
}
}

View File

@@ -21,160 +21,171 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.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).
*
/**
* 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: ExceptionTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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();
}
}
/**
* @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);
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitExceptionTable(this);
}
/**
* Dump exceptions attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
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]);
}
}
/**
* 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();
}
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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 String representation, i.e., a list of thrown exceptions.
*/
@Override
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 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;
}
/**
* @return deep copy of this attribute
*/
@Override
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;
}
}

View File

@@ -23,168 +23,175 @@ import org.apache.bcel.generic.Type;
import org.apache.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.
*
* This class represents the field info structure, i.e., the representation for
* a variable in the class. See JVM specification for details.
*
* @version $Id: Field.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public final class Field extends FieldOrMethod {
private static BCELComparator _cmp = new BCELComparator() {
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
@Override
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());
}
@Override
public int hashCode(Object o) {
Field THIS = (Field) o;
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
}
};
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);
}
/**
* 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);
}
/**
* @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
*/
@Override
public void accept(Visitor v) {
v.visitField(this);
}
/**
* Construct object from file stream.
* @param file Input stream
*/
Field(DataInputStream file, ConstantPool constant_pool) throws IOException,
ClassFormatException {
super(file, constant_pool);
}
/**
* @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.
*/
@Override
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();
}
/**
* @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);
}
/**
* @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());
}
/**
* 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 Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @param comparator
* Comparison strategy object
*/
public static void setComparator(BCELComparator comparator) {
_cmp = comparator;
}
/**
* @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 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)
*/
@Override
public boolean equals(Object obj) {
return _cmp.equals(this, obj);
}
/**
* 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);
}
/**
* 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()
*/
@Override
public int hashCode() {
return _cmp.hashCode(this);
}
}

View File

@@ -21,186 +21,190 @@ import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.bcel.Constants;
/**
/**
* Abstract super class for fields and methods.
*
*
* @version $Id: FieldOrMethod.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node {
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 ConstantPool constant_pool;
/**
*
*/
private static final long serialVersionUID = 1L;
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 ConstantPool constant_pool;
FieldOrMethod() {
}
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);
}
}
/**
* 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());
}
/**
* @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);
}
}
/**
* 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);
}
}
/**
* @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;
}
/**
* @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);
}
/**
* @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;
}
/**
* 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 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 Collection of object attributes.
*/
public final Attribute[] getAttributes() {
return attributes;
}
/**
* @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;
}
/**
* @param attributes Collection of object attributes.
*/
public final void setAttributes( Attribute[] attributes ) {
this.attributes = attributes;
attributes_count = (attributes == null) ? 0 : attributes.length;
}
/**
* @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 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 ) {
try {
FieldOrMethod c = (FieldOrMethod) clone();
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;
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* @return deep copy of this field
*/
protected FieldOrMethod copy_(ConstantPool _constant_pool) {
try {
FieldOrMethod c = (FieldOrMethod) clone();
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;
} catch (CloneNotSupportedException e) {
return null;
}
}
}

View File

@@ -22,193 +22,194 @@ import java.io.IOException;
import java.io.Serializable;
import org.apache.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.
*
/**
* 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: InnerClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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(DataInputStream 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;
}
/**
* Construct object from file stream.
* @param file Input stream
* @throws IOException
*/
InnerClass(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), 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
*/
@Override
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);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* @return access flags of inner class.
*/
public final int getInnerAccessFlags() {
return inner_access_flags;
}
/**
* @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 class index of inner class.
*/
public final int getInnerClassIndex() {
return inner_class_index;
}
/**
* @return String representation.
*/
@Override
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 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;
}
/**
* @return deep copy of this object
*/
public InnerClass copy() {
try {
return (InnerClass) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
}

View File

@@ -22,129 +22,139 @@ import java.io.IOException;
import org.apache.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.
*
* 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: InnerClasses.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @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;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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);
}
}
/**
* @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);
}
/**
* 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
*/
@Override
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
*/
@Override
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);
}
}
/**
* 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);
}
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
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();
}
/**
* 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;
}
/**
* @return deep copy of this attribute
*/
@Override
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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -23,119 +23,122 @@ 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.
*
* the source that corresponds to a relative address in the byte code. This is
* used for debugging purposes.
*
* @version $Id: LineNumber.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see LineNumberTable
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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(DataInputStream 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;
}
/**
* Construct object from file stream.
* @param file Input stream
* @throws IOException
*/
LineNumber(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), 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
*/
@Override
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);
}
/**
* @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;
}
/**
* @return Corresponding source line
*/
public final int getLineNumber() {
return line_number;
}
/**
* @return PC in code
*/
public final int getStartPC() {
return start_pc;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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 String representation
*/
@Override
public final String toString() {
return "LineNumber(" + start_pc + ", " + 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;
}
/**
* @return deep copy of this object
*/
public LineNumber copy() {
try {
return (LineNumber) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
}

View File

@@ -22,187 +22,202 @@ import java.io.IOException;
import org.apache.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.
*
* 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: LineNumberTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/*
* 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);
}
}
/*
* @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);
}
/**
* 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
*/
@Override
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
*/
@Override
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);
}
}
/**
* 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);
}
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
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();
}
/**
* 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 deep copy of this attribute
*/
@Override
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;
}
/**
* @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;
}
public final int getTableLength() {
return line_number_table_length;
}
}

View File

@@ -25,224 +25,232 @@ import org.apache.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: LocalVariable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see LocalVariableTable
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see LocalVariableTable
*/
public final class LocalVariable implements Constants, Cloneable, Node, Serializable {
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;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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(DataInputStream 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;
}
/**
* Construct object from file stream.
* @param file Input stream
* @throws IOException
*/
LocalVariable(DataInputStream file, ConstantPool constant_pool) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), file.readUnsignedShort(), 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
*/
@Override
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);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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 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 Constant pool used by this object.
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
/**
* @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;
}
/**
* @return Variable is valid within getStartPC() .. getStartPC()+getLength()
*/
public final int getLength() {
return length;
}
/**
* @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;
}
/**
* @return Variable name.
*/
public final String getName() {
ConstantUtf8 c;
c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8);
return c.getBytes();
}
/**
* @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;
}
/**
* @return Index in constant pool of variable name.
*/
public final int getNameIndex() {
return name_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 Signature.
*/
public final String getSignature() {
ConstantUtf8 c;
c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return string representation.
*/
@Override
public final String toString() {
String name = getName(), signature = Utility
.signatureToString(getSignature());
return "LocalVariable(start_pc = " + start_pc + ", length = " + length
+ ", index = " + index + ":" + signature + " " + name + ")";
}
/**
* @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;
}
/**
* @return deep copy of this object
*/
public LocalVariable copy() {
try {
return (LocalVariable) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
}

View File

@@ -22,176 +22,187 @@ import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class represents colection of local variables in a
* method. This attribute is contained in the <em>Code</em> attribute.
*
* This class represents colection of local variables in a method. This
* attribute is contained in the <em>Code</em> attribute.
*
* @version $Id: LocalVariableTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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);
}
}
/**
* @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);
}
/**
* 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
*/
@Override
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
*/
@Override
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);
}
}
/**
* 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);
}
}
/**
* @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
*
*/
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;
}
/**
* 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);
}
/**
* @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;
}
/**
* 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 String representation.
*/
@Override
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
*/
@Override
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;
}
/**
* @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;
}
public final int getTableLength() {
return local_variable_table_length;
}
}

View File

@@ -23,232 +23,238 @@ import org.apache.bcel.generic.Type;
import org.apache.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.
*
* 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: Method.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public final class Method extends FieldOrMethod {
private static BCELComparator _cmp = new BCELComparator() {
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
@Override
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());
}
@Override
public int hashCode(Object o) {
Method THIS = (Method) o;
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
}
};
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);
}
/**
* Empty constructor, all attributes have to be defined via `setXXX'
* methods. Use at your own risk.
*/
public Method() {
}
/**
* 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);
}
/**
* 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);
}
/**
* 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
*/
@Override
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;
}
/**
* 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);
}
/**
* @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();
}
/**
* @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);
}
/**
* @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.
*/
@Override
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();
}
/**
* 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 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 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 array of method argument types
*/
public Type[] getArgumentTypes() {
return Type.getArgumentTypes(getSignature());
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @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;
}
/**
* @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)
*/
@Override
public boolean equals(Object obj) {
return _cmp.equals(this, obj);
}
/** @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);
}
/**
* 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()
*/
@Override
public int hashCode() {
return _cmp.hashCode(this);
}
}

View File

@@ -18,11 +18,11 @@ package org.apache.bcel.classfile;
/**
* Denote class to have an accept method();
*
*
* @version $Id: Node.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public interface Node {
public void accept( Visitor obj );
public void accept(Visitor obj);
}

View File

@@ -22,146 +22,154 @@ import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from <em>Attribute</em> and represents a reference
* to a PMG attribute.
*
* This class is derived from <em>Attribute</em> and represents a reference to a
* PMG attribute.
*
* @version $Id: PMGClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @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;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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, DataInputStream 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;
}
/**
* 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, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(pmg_index);
file.writeShort(pmg_class_index);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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");
}
/**
* @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;
}
/**
* 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 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 Index in constant pool of source file name.
*/
public final int getPMGClassIndex() {
return pmg_class_index;
}
/**
* @return String representation
*/
@Override
public final String toString() {
return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")";
}
/**
* @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();
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
return (PMGClass) clone();
}
}

View File

@@ -23,251 +23,251 @@ import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class is derived from <em>Attribute</em> and represents a reference
* to a GJ attribute.
*
* This class is derived from <em>Attribute</em> and represents a reference to a
* GJ attribute.
*
* @version $Id: Signature.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
*/
public final class Signature extends Attribute {
private int signature_index;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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, DataInputStream 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;
}
/**
* 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, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, file.readUnsignedShort(), 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(signature_index);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @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 {
/**
* 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);
}
MyByteArrayInputStream(String data) {
super(data.getBytes());
}
final String getData() {
return new String(buf);
}
/**
* @return Index in constant pool of source file name.
*/
public final int getSignatureIndex() {
return signature_index;
}
final void unread() {
if (pos > 0) {
pos--;
}
}
}
private static boolean identStart(int ch) {
return ch == 'T' || ch == 'L';
}
/**
* @param signature_index the index info the constant pool of this signature
*/
public final void setSignatureIndex( int signature_index ) {
this.signature_index = signature_index;
}
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);
}
}
/**
* @return GJ signature.
*/
public final String getSignature() {
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(signature_index,
Constants.CONSTANT_Utf8);
return c.getBytes();
}
public static String translate(String s) {
// System.out.println("Sig:" + s);
StringBuffer buf = new StringBuffer();
matchGJIdent(new MyByteArrayInputStream(s), buf);
return buf.toString();
}
/**
* Extends ByteArrayInputStream to make 'unreading' chars possible.
*/
private static final class MyByteArrayInputStream extends ByteArrayInputStream {
public static final boolean isFormalParameterList(String s) {
return s.startsWith("<") && (s.indexOf(':') > 0);
}
MyByteArrayInputStream(String data) {
super(data.getBytes());
}
public static final boolean isActualParameterList(String s) {
return s.startsWith("L") && s.endsWith(">;");
}
/**
* @return String representation
*/
@Override
public final String toString() {
String s = getSignature();
return "Signature(" + s + ")";
}
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();
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
return (Signature) clone();
}
}

View File

@@ -22,124 +22,134 @@ import java.io.IOException;
import org.apache.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.
*
* 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: SourceFile.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
*/
public final class SourceFile extends Attribute {
private int sourcefile_index;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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, DataInputStream 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;
}
/**
* 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, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, file.readUnsignedShort(), 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(sourcefile_index);
}
/**
* @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;
}
/**
* @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;
}
/**
* 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);
}
/**
* @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
*/
@Override
public final String toString() {
return "SourceFile(" + getSourceFileName() + ")";
}
/**
* 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();
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
return (SourceFile) clone();
}
}

View File

@@ -22,132 +22,141 @@ import java.io.IOException;
import org.apache.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>
* 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
*
* 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: StackMap.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code
* @see StackMapEntry
* @see StackMapType
* @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
/**
*
*/
private static final long serialVersionUID = 1L;
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);
}
/*
* @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
*/
@Override
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);
}
}
/**
* 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);
}
}
/**
* @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;
}
/**
* 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 String representation.
*/
@Override
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
*/
@Override
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;
}
/**
* @return Array of stack map entries
*/
public final StackMapEntry[] getStackMap() {
return map;
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitStackMap(this);
}
/**
* @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;
}
public final int getMapLength() {
return map_length;
}
}

View File

@@ -21,192 +21,181 @@ 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
*
* 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: StackMapEntry.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see StackMap
* @see StackMapType
* @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;
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);
}
}
/**
* 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);
}
}
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;
}
/**
* @return String representation.
*/
@Override
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;
}
/**
* 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);
}
}
public int getByteCodeOffset() {
return byte_code_offset;
}
public void setNumberOfLocals(int n) {
number_of_locals = n;
}
/**
* @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 int getNumberOfLocals() {
return number_of_locals;
}
public void setTypesOfLocals(StackMapType[] t) {
types_of_locals = t;
}
public void setByteCodeOffset( int b ) {
byte_code_offset = b;
}
public StackMapType[] getTypesOfLocals() {
return types_of_locals;
}
public void setNumberOfStackItems(int n) {
number_of_stack_items = n;
}
public int getByteCodeOffset() {
return byte_code_offset;
}
public int getNumberOfStackItems() {
return number_of_stack_items;
}
public void setTypesOfStackItems(StackMapType[] t) {
types_of_stack_items = t;
}
public void setNumberOfLocals( int n ) {
number_of_locals = n;
}
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;
}
public int getNumberOfLocals() {
return number_of_locals;
}
/**
* 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;
}
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;
}
/**
* @param constant_pool
* Constant pool to be used for this object.
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
}

View File

@@ -22,140 +22,139 @@ import java.io.IOException;
import org.apache.bcel.Constants;
/**
* This class represents the type of a local variable or item on stack
* used in the StackMap entries.
*
* This class represents the type of a local variable or item on stack used in
* the StackMap entries.
*
* @version $Id: StackMapType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see StackMapEntry
* @see StackMap
* @see Constants
* @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;
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(DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(file.readByte(), -1, constant_pool);
if (hasIndex()) {
setIndex(file.readShort());
}
setConstantPool(constant_pool);
}
/**
* Construct object from file stream.
* @param file Input stream
* @throws IOException
*/
StackMapType(DataInputStream 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;
}
/**
* @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 byte getType() {
return type;
}
public void setIndex(int t) {
index = t;
}
public void setType( byte t ) {
if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) {
throw new RuntimeException("Illegal type for StackMapType: " + t);
}
type = 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());
}
}
public byte getType() {
return type;
}
/**
* @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 "";
}
}
public void setIndex( int t ) {
index = t;
}
/**
* @return String representation
*/
@Override
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 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;
}
/**
* @return Constant pool used by this object.
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
/**
* 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;
}
/**
* @param constant_pool
* Constant pool to be used for this object.
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
}

View File

@@ -23,128 +23,137 @@ import org.apache.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.
*
* `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: Synthetic.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute
*/
public final class Synthetic extends Attribute {
private byte[] bytes;
/**
*
*/
private static final long serialVersionUID = 1L;
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());
}
/**
* 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");
}
}
/**
* @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;
}
/**
* 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
*/
@Override
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
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
if (length > 0) {
file.write(bytes, 0, length);
}
}
/**
* 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");
}
}
/**
* @return data bytes.
*/
public final byte[] getBytes() {
return bytes;
}
/**
* @param bytes
*/
public final void setBytes(byte[] bytes) {
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.visitSynthetic(this);
}
/**
* @return String representation.
*/
@Override
public final String toString() {
StringBuffer buf = new StringBuffer("Synthetic");
if (length > 0) {
buf.append(" ").append(Utility.toHexString(bytes));
}
return buf.toString();
}
/**
* 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;
}
/**
* @return deep copy of this attribute
*/
@Override
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;
}
}

View File

@@ -22,167 +22,178 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.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,
* 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.bcel.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
*
*
*
* @version $Id: Unknown.java 386056 2006-03-15 11:31:56Z tcurdt $
* @see org.apache.bcel.classfile.Attribute
* @see org.apache.bcel.classfile.AttributeReader
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @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();
/**
*
*/
private static final long serialVersionUID = 1L;
private byte[] bytes;
private String name;
private static Map<String, Unknown> unknown_attributes = new HashMap<String, Unknown>();
/**
* @return array of unknown attributes, but just one for each kind.
*/
static Unknown[] getUnknownAttributes() {
Unknown[] unknowns = new Unknown[unknown_attributes.size()];
Iterator<Unknown> entries = unknown_attributes.values().iterator();
for (int i = 0; entries.hasNext(); i++) {
unknowns[i] = entries.next();
}
unknown_attributes.clear();
return unknowns;
}
/** @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);
}
/**
* 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());
}
/**
* 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
*/
@Override
public void accept(Visitor v) {
v.visitUnknown(this);
}
/**
* 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);
}
/**
* Dump unknown bytes to file stream.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
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;
}
/**
* 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);
}
}
/**
* @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;
}
/**
* 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);
}
/**
* @return String representation.
*/
@Override
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 + ")";
}
/**
* 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;
}
/**
* @return deep copy of this attribute
*/
@Override
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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,111 +17,80 @@
package org.apache.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.
*
* 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: Visitor.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public interface Visitor {
//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 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 visitCodeException( CodeException obj );
public void visitConstantClass(ConstantClass obj);
public void visitConstantDouble(ConstantDouble obj);
public void visitConstantClass( ConstantClass obj );
public void visitConstantFieldref(ConstantFieldref obj);
public void visitConstantFloat(ConstantFloat obj);
public void visitConstantDouble( ConstantDouble obj );
public void visitConstantInteger(ConstantInteger obj);
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
public void visitConstantFieldref( ConstantFieldref obj );
public void visitConstantLong(ConstantLong obj);
public void visitConstantMethodref(ConstantMethodref obj);
public void visitConstantFloat( ConstantFloat obj );
public void visitConstantNameAndType(ConstantNameAndType obj);
public void visitConstantPool(ConstantPool obj);
public void visitConstantInteger( ConstantInteger obj );
public void visitConstantString(ConstantString obj);
public void visitConstantUtf8(ConstantUtf8 obj);
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj );
public void visitConstantValue(ConstantValue obj);
public void visitDeprecated(Deprecated obj);
public void visitConstantLong( ConstantLong obj );
public void visitExceptionTable(ExceptionTable obj);
public void visitField(Field obj);
public void visitConstantMethodref( ConstantMethodref obj );
public void visitInnerClass(InnerClass obj);
public void visitInnerClasses(InnerClasses obj);
public void visitConstantNameAndType( ConstantNameAndType obj );
public void visitJavaClass(JavaClass obj);
public void visitLineNumber(LineNumber obj);
public void visitConstantPool( ConstantPool obj );
public void visitLineNumberTable(LineNumberTable obj);
public void visitLocalVariable(LocalVariable obj);
public void visitConstantString( ConstantString obj );
public void visitLocalVariableTable(LocalVariableTable obj);
public void visitMethod(Method obj);
public void visitConstantUtf8( ConstantUtf8 obj );
public void visitSignature(Signature obj);
public void visitSourceFile(SourceFile obj);
public void visitConstantValue( ConstantValue obj );
public void visitSynthetic(Synthetic obj);
public void visitUnknown(Unknown obj);
public void visitDeprecated( Deprecated obj );
public void visitStackMap(StackMap 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 visitStackMapEntry(StackMapEntry obj);
}