You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-dev@jakarta.apache.org by md...@apache.org on 2003/05/23 09:50:53 UTC
cvs commit: jakarta-bcel/src/java/org/apache/bcel/classfile JavaClass.java Field.java Method.java Constant.java
mdahm 2003/05/23 00:50:52
Modified: src/java/org/apache/bcel/classfile JavaClass.java Field.java
Method.java Constant.java
Added: src/java/org/apache/bcel/util BCELComparator.java
Log:
Added BCELComparator
equals() and hascode() may be paramerized by a strategy object
By default names and signatures have to be equal
Revision Changes Path
1.1 jakarta-bcel/src/java/org/apache/bcel/util/BCELComparator.java
Index: BCELComparator.java
===================================================================
package org.apache.bcel.util;
/**
* Used for BCEL comparison strategy
*
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @version $Id: BCELComparator.java,v 1.1 2003/05/23 07:50:51 mdahm Exp $
*/
public interface BCELComparator {
/**
* Compare two objects and return what THIS.equals(THAT) should return
*
* @param THIS
* @param THAT
* @return
*/
public boolean equals(Object THIS, Object THAT);
/**
* Return hashcode for THIS.hashCode()
*
* @param THIS
* @param THAT
* @return
*/
public int hashCode(Object THIS);
}
1.14 +337 -235 jakarta-bcel/src/java/org/apache/bcel/classfile/JavaClass.java
Index: JavaClass.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/classfile/JavaClass.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- JavaClass.java 11 Jul 2002 19:39:04 -0000 1.13
+++ JavaClass.java 23 May 2003 07:50:52 -0000 1.14
@@ -54,59 +54,72 @@
* <http://www.apache.org/>.
*/
-import org.apache.bcel.Constants;
-import org.apache.bcel.util.SyntheticRepository;
-import org.apache.bcel.util.ClassVector;
-import org.apache.bcel.util.ClassQueue;
-import org.apache.bcel.generic.Type;
+import org.apache.bcel.Constants;
+import org.apache.bcel.util.BCELComparator;
+import org.apache.bcel.util.SyntheticRepository;
+import org.apache.bcel.util.ClassVector;
+import org.apache.bcel.util.ClassQueue;
+import org.apache.bcel.generic.Type;
-import java.io.*;
-import java.util.StringTokenizer;
+import java.io.*;
+import java.util.StringTokenizer;
/**
* Represents a Java class, i.e., the data structures, constant pool,
* fields, methods and commands contained in a Java .class file.
- * See <a href="ftp://java.sun.com/docs/specs/">JVM
- * specification</a> for details.
-
+ * See <a href="ftp://java.sun.com/docs/specs/">JVM specification</a> for details.
* The intent of this class is to represent a parsed or otherwise existing
* class file. Those interested in programatically generating classes
* should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
* @version $Id$
* @see org.apache.bcel.generic.ClassGen
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public class JavaClass extends AccessFlags implements Cloneable, Node {
- private String file_name;
- private String package_name;
- private String source_file_name = "<Unknown>";
- private int class_name_index;
- private int superclass_name_index;
- private String class_name;
- private String superclass_name;
- private int major, minor; // Compiler version
+ private String file_name;
+ private String package_name;
+ private String source_file_name = "<Unknown>";
+ private int class_name_index;
+ private int superclass_name_index;
+ private String class_name;
+ private String superclass_name;
+ private int major, minor; // Compiler version
private ConstantPool constant_pool; // Constant pool
- private int[] interfaces; // implemented interfaces
- private String[] interface_names;
- private Field[] fields; // Fields, i.e., variables of class
- private Method[] methods; // methods defined in the class
- private Attribute[] attributes; // attributes defined in the class
- private byte source = HEAP; // Generated in memory
+ private int[] interfaces; // implemented interfaces
+ private String[] interface_names;
+ private Field[] fields; // Fields, i.e., variables of class
+ private Method[] methods; // methods defined in the class
+ private Attribute[] attributes; // attributes defined in the class
+ private byte source = HEAP; // Generated in memory
public static final byte HEAP = 1;
public static final byte FILE = 2;
- public static final byte ZIP = 3;
+ public static final byte ZIP = 3;
static boolean debug = false; // Debugging on/off
- static char sep = '/'; // directory separator
+ static char sep = '/'; // directory separator
+
+ private static BCELComparator _cmp = new BCELComparator() {
+ public boolean equals(Object o1, Object o2) {
+ JavaClass THIS = (JavaClass)o1;
+ JavaClass THAT = (JavaClass)o2;
+
+ return THIS.getClassName().equals(THAT.getClassName());
+ }
+
+ public int hashCode(Object o) {
+ JavaClass THIS = (JavaClass)o;
+ return THIS.getClassName().hashCode();
+ }
+ };
/**
* In cases where we go ahead and create something,
* use the default SyntheticRepository, because we
* don't know any better.
*/
- private transient org.apache.bcel.util.Repository repository =
+ private transient org.apache.bcel.util.Repository repository =
SyntheticRepository.getInstance();
/**
@@ -127,46 +140,46 @@
* @param attributes Class attributes
* @param source Read from file or generated in memory?
*/
- public JavaClass(int class_name_index,
- int superclass_name_index,
- String file_name,
- int major,
- int minor,
- int access_flags,
- ConstantPool constant_pool,
- int[] interfaces,
- Field[] fields,
- Method[] methods,
- Attribute[] attributes,
- byte source)
- {
- if(interfaces == null) // Allowed for backward compatibility
+ public JavaClass(
+ int class_name_index,
+ int superclass_name_index,
+ String file_name,
+ int major,
+ int minor,
+ int access_flags,
+ ConstantPool constant_pool,
+ int[] interfaces,
+ Field[] fields,
+ Method[] methods,
+ Attribute[] attributes,
+ byte source) {
+ if (interfaces == null) // Allowed for backward compatibility
interfaces = new int[0];
- if(attributes == null)
+ if (attributes == null)
this.attributes = new Attribute[0];
- if(fields == null)
+ if (fields == null)
fields = new Field[0];
- if(methods == null)
+ if (methods == null)
methods = new Method[0];
- this.class_name_index = class_name_index;
+ this.class_name_index = class_name_index;
this.superclass_name_index = superclass_name_index;
- this.file_name = file_name;
- this.major = major;
- this.minor = minor;
- this.access_flags = access_flags;
- this.constant_pool = constant_pool;
- this.interfaces = interfaces;
- this.fields = fields;
- this.methods = methods;
- this.attributes = attributes;
- this.source = source;
+ this.file_name = file_name;
+ this.major = major;
+ this.minor = minor;
+ this.access_flags = access_flags;
+ this.constant_pool = constant_pool;
+ this.interfaces = interfaces;
+ this.fields = fields;
+ this.methods = methods;
+ this.attributes = attributes;
+ this.source = source;
// Get source file name if available
- for(int i=0; i < attributes.length; i++) {
- if(attributes[i] instanceof SourceFile) {
- source_file_name = ((SourceFile)attributes[i]).getSourceFileName();
- break;
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i] instanceof SourceFile) {
+ source_file_name = ((SourceFile)attributes[i]).getSourceFileName();
+ break;
}
}
@@ -174,27 +187,34 @@
* `ConstantClass' but we check that anyway via the
* `ConstPool.getConstant' method.
*/
- class_name = constant_pool.getConstantString(class_name_index,
- Constants.CONSTANT_Class);
+ class_name =
+ constant_pool.getConstantString(
+ class_name_index,
+ Constants.CONSTANT_Class);
class_name = Utility.compactClassName(class_name, false);
int index = class_name.lastIndexOf('.');
- if(index < 0)
+ if (index < 0)
package_name = "";
else
package_name = class_name.substring(0, index);
- if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object
- superclass_name = constant_pool.getConstantString(superclass_name_index,
- Constants.CONSTANT_Class);
+ if (superclass_name_index > 0) {
+ // May be zero -> class is java.lang.Object
+ superclass_name =
+ constant_pool.getConstantString(
+ superclass_name_index,
+ Constants.CONSTANT_Class);
superclass_name = Utility.compactClassName(superclass_name, false);
- }
- else
- superclass_name = "java.lang.Object";
+ } else
+ superclass_name = "java.lang.Object";
interface_names = new String[interfaces.length];
- for(int i=0; i < interfaces.length; i++) {
- String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
+ for (int i = 0; i < interfaces.length; i++) {
+ String str =
+ constant_pool.getConstantString(
+ interfaces[i],
+ Constants.CONSTANT_Class);
interface_names[i] = Utility.compactClassName(str, false);
}
}
@@ -214,22 +234,33 @@
* @param methods Class methods
* @param attributes Class attributes
*/
- public JavaClass(int class_name_index,
- int superclass_name_index,
- String file_name,
- int major,
- int minor,
- int access_flags,
- ConstantPool constant_pool,
- int[] interfaces,
- Field[] fields,
- Method[] methods,
- Attribute[] attributes) {
- this(class_name_index, superclass_name_index, file_name, major, minor, access_flags,
- constant_pool, interfaces, fields, methods, attributes, HEAP);
+ public JavaClass(
+ int class_name_index,
+ int superclass_name_index,
+ String file_name,
+ int major,
+ int minor,
+ int access_flags,
+ ConstantPool constant_pool,
+ int[] interfaces,
+ Field[] fields,
+ Method[] methods,
+ Attribute[] attributes) {
+ this(
+ class_name_index,
+ superclass_name_index,
+ file_name,
+ major,
+ minor,
+ access_flags,
+ constant_pool,
+ interfaces,
+ fields,
+ methods,
+ attributes,
+ HEAP);
}
-
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
@@ -244,7 +275,7 @@
/* Print debug information depending on `JavaClass.debug'
*/
static final void Debug(String str) {
- if(debug)
+ if (debug)
System.out.println(str);
}
@@ -254,15 +285,14 @@
* @param file Output file
* @throws IOException
*/
- public void dump(File file) throws IOException
- {
+ public void dump(File file) throws IOException {
String parent = file.getParent();
- if(parent != null) {
+ if (parent != null) {
File dir = new File(parent);
-
- if(dir != null)
- dir.mkdirs();
+
+ if (dir != null)
+ dir.mkdirs();
}
dump(new DataOutputStream(new FileOutputStream(file)));
@@ -274,8 +304,7 @@
* @param file_name Output file name
* @exception IOException
*/
- public void dump(String file_name) throws IOException
- {
+ public void dump(String file_name) throws IOException {
dump(new File(file_name));
}
@@ -283,15 +312,19 @@
* @return class in binary format
*/
public byte[] getBytes() {
- ByteArrayOutputStream s = new ByteArrayOutputStream();
- DataOutputStream ds = new DataOutputStream(s);
+ ByteArrayOutputStream s = new ByteArrayOutputStream();
+ DataOutputStream ds = new DataOutputStream(s);
try {
dump(ds);
- } catch(IOException e) {
+ } catch (IOException e) {
e.printStackTrace();
} finally {
- try { ds.close(); } catch(IOException e2) { e2.printStackTrace(); }
+ try {
+ ds.close();
+ } catch (IOException e2) {
+ e2.printStackTrace();
+ }
}
return s.toByteArray();
@@ -313,36 +346,34 @@
* @param file Output stream
* @exception IOException
*/
- public void dump(DataOutputStream file) throws IOException
- {
+ public void dump(DataOutputStream file) throws IOException {
file.writeInt(0xcafebabe);
file.writeShort(minor);
file.writeShort(major);
constant_pool.dump(file);
-
+
file.writeShort(access_flags);
file.writeShort(class_name_index);
file.writeShort(superclass_name_index);
file.writeShort(interfaces.length);
- for(int i=0; i < interfaces.length; i++)
+ for (int i = 0; i < interfaces.length; i++)
file.writeShort(interfaces[i]);
file.writeShort(fields.length);
- for(int i=0; i < fields.length; i++)
+ for (int i = 0; i < fields.length; i++)
fields[i].dump(file);
file.writeShort(methods.length);
- for(int i=0; i < methods.length; i++)
+ for (int i = 0; i < methods.length; i++)
methods[i].dump(file);
- if(attributes != null) {
+ if (attributes != null) {
file.writeShort(attributes.length);
- for(int i=0; i < attributes.length; i++)
- attributes[i].dump(file);
- }
- else
+ for (int i = 0; i < attributes.length; i++)
+ attributes[i].dump(file);
+ } else
file.writeShort(0);
file.close();
@@ -351,72 +382,94 @@
/**
* @return Attributes of the class.
*/
- public Attribute[] getAttributes() { return attributes; }
+ public Attribute[] getAttributes() {
+ return attributes;
+ }
/**
* @return Class name.
*/
- public String getClassName() { return class_name; }
+ public String getClassName() {
+ return class_name;
+ }
/**
* @return Package name.
*/
- public String getPackageName() { return package_name; }
+ public String getPackageName() {
+ return package_name;
+ }
/**
* @return Class name index.
*/
- public int getClassNameIndex() { return class_name_index; }
+ public int getClassNameIndex() {
+ return class_name_index;
+ }
/**
* @return Constant pool.
*/
- public ConstantPool getConstantPool() { return constant_pool; }
+ public ConstantPool getConstantPool() {
+ return constant_pool;
+ }
/**
* @return Fields, i.e., variables of the class. Like the JVM spec
* mandates for the classfile format, these fields are those specific to
* this class, and not those of the superclass or superinterfaces.
*/
- public Field[] getFields() { return fields; }
+ public Field[] getFields() {
+ return fields;
+ }
/**
* @return File name of class, aka SourceFile attribute value
*/
- public String getFileName() { return file_name; }
+ public String getFileName() {
+ return file_name;
+ }
/**
* @return Names of implemented interfaces.
*/
- public String[] getInterfaceNames() { return interface_names; }
+ public String[] getInterfaceNames() {
+ return interface_names;
+ }
/**
* @return Indices in constant pool of implemented interfaces.
*/
- public int[] getInterfaceIndices() { return interfaces; }
+ public int[] getInterfaceIndices() {
+ return interfaces;
+ }
/**
* @return Major number of class file version.
*/
- public int getMajor() { return major; }
+ public int getMajor() {
+ return major;
+ }
/**
* @return Methods of the class.
*/
- public Method[] getMethods() { return methods; }
+ public Method[] getMethods() {
+ return methods;
+ }
/**
* @return A org.apache.bcel.classfile.Method corresponding to
* java.lang.reflect.Method if any
*/
public Method getMethod(java.lang.reflect.Method m) {
- for(int i = 0; i < methods.length; i++) {
+ for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
- if(m.getName().equals(method.getName()) &&
- (m.getModifiers() == method.getModifiers()) &&
- Type.getSignature(m).equals(method.getSignature())) {
- return method;
+ if (m.getName().equals(method.getName())
+ && (m.getModifiers() == method.getModifiers())
+ && Type.getSignature(m).equals(method.getSignature())) {
+ return method;
}
}
@@ -426,37 +479,46 @@
/**
* @return Minor number of class file version.
*/
- public int getMinor() { return minor; }
+ public int getMinor() {
+ return minor;
+ }
/**
* @return sbsolute path to file where this class was read from
*/
- public String getSourceFileName() { return source_file_name; }
+ public String getSourceFileName() {
+ return source_file_name;
+ }
/**
* @return Superclass name.
*/
- public String getSuperclassName() { return superclass_name; }
+ public String getSuperclassName() {
+ return superclass_name;
+ }
/**
* @return Class name index.
*/
- public int getSuperclassNameIndex() { return superclass_name_index; }
+ public int getSuperclassNameIndex() {
+ return superclass_name_index;
+ }
static {
// Debugging ... on/off
String debug = System.getProperty("JavaClass.debug");
- if(debug != null)
+ if (debug != null)
JavaClass.debug = new Boolean(debug).booleanValue();
// Get path separator either / or \ usually
String sep = System.getProperty("file.separator");
- if(sep != null)
+ if (sep != null)
try {
- JavaClass.sep = sep.charAt(0);
- } catch(StringIndexOutOfBoundsException e) {} // Never reached
+ JavaClass.sep = sep.charAt(0);
+ } catch (StringIndexOutOfBoundsException e) {
+ } // Never reached
}
/**
@@ -464,121 +526,124 @@
*/
public void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
- }
+ }
/**
* @param class_name .
*/
public void setClassName(String class_name) {
this.class_name = class_name;
- }
+ }
/**
* @param class_name_index .
*/
public void setClassNameIndex(int class_name_index) {
this.class_name_index = class_name_index;
- }
+ }
/**
* @param constant_pool .
*/
public void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
- }
+ }
/**
* @param fields .
*/
public void setFields(Field[] fields) {
this.fields = fields;
- }
+ }
/**
* Set File name of class, aka SourceFile attribute value
*/
public void setFileName(String file_name) {
this.file_name = file_name;
- }
+ }
/**
* @param interface_names .
*/
public void setInterfaceNames(String[] interface_names) {
this.interface_names = interface_names;
- }
+ }
/**
* @param interfaces .
*/
public void setInterfaces(int[] interfaces) {
this.interfaces = interfaces;
- }
+ }
/**
* @param major .
*/
public void setMajor(int major) {
this.major = major;
- }
+ }
/**
* @param methods .
*/
public void setMethods(Method[] methods) {
this.methods = methods;
- }
+ }
/**
* @param minor .
*/
public void setMinor(int minor) {
this.minor = minor;
- }
+ }
/**
* Set absolute path to file this class was read from.
*/
public void setSourceFileName(String source_file_name) {
this.source_file_name = source_file_name;
- }
+ }
/**
* @param superclass_name .
*/
public void setSuperclassName(String superclass_name) {
this.superclass_name = superclass_name;
- }
+ }
/**
* @param superclass_name_index .
*/
public void setSuperclassNameIndex(int superclass_name_index) {
this.superclass_name_index = superclass_name_index;
- }
+ }
/**
* @return String representing class contents.
*/
public String toString() {
String access = Utility.accessToString(access_flags, true);
- access = access.equals("")? "" : (access + " ");
+ access = access.equals("") ? "" : (access + " ");
- StringBuffer buf = new StringBuffer(access +
- Utility.classOrInterface(access_flags) +
- " " +
- class_name + " extends " +
- Utility.compactClassName(superclass_name,
- false) + '\n');
+ StringBuffer buf =
+ new StringBuffer(
+ access
+ + Utility.classOrInterface(access_flags)
+ + " "
+ + class_name
+ + " extends "
+ + Utility.compactClassName(superclass_name, false)
+ + '\n');
int size = interfaces.length;
- if(size > 0) {
+ if (size > 0) {
buf.append("implements\t\t");
- for(int i=0; i < size; i++) {
- buf.append(interface_names[i]);
- if(i < size - 1)
- buf.append(", ");
+ for (int i = 0; i < size; i++) {
+ buf.append(interface_names[i]);
+ if (i < size - 1)
+ buf.append(", ");
}
buf.append('\n');
@@ -591,32 +656,32 @@
buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n");
buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n");
- if(attributes.length > 0) {
+ if (attributes.length > 0) {
buf.append("\nAttribute(s):\n");
- for(int i=0; i < attributes.length; i++)
- buf.append(indent(attributes[i]));
+ for (int i = 0; i < attributes.length; i++)
+ buf.append(indent(attributes[i]));
}
- if(fields.length > 0) {
+ if (fields.length > 0) {
buf.append("\n" + fields.length + " fields:\n");
- for(int i=0; i < fields.length; i++)
- buf.append("\t" + fields[i] + '\n');
+ for (int i = 0; i < fields.length; i++)
+ buf.append("\t" + fields[i] + '\n');
}
- if(methods.length > 0) {
+ if (methods.length > 0) {
buf.append("\n" + methods.length + " methods:\n");
- for(int i=0; i < methods.length; i++)
- buf.append("\t" + methods[i] + '\n');
+ for (int i = 0; i < methods.length; i++)
+ buf.append("\t" + methods[i] + '\n');
}
return buf.toString();
- }
+ }
private static final String indent(Object obj) {
StringTokenizer tok = new StringTokenizer(obj.toString(), "\n");
StringBuffer buf = new StringBuffer();
- while(tok.hasMoreTokens())
+ while (tok.hasMoreTokens())
buf.append("\t" + tok.nextToken() + "\n");
return buf.toString();
@@ -630,22 +695,23 @@
try {
c = (JavaClass)clone();
- } catch(CloneNotSupportedException e) {}
+ } catch (CloneNotSupportedException e) {
+ }
- c.constant_pool = constant_pool.copy();
- c.interfaces = (int[])interfaces.clone();
+ c.constant_pool = constant_pool.copy();
+ c.interfaces = (int[])interfaces.clone();
c.interface_names = (String[])interface_names.clone();
c.fields = new Field[fields.length];
- for(int i=0; i < fields.length; i++)
+ for (int i = 0; i < fields.length; i++)
c.fields[i] = fields[i].copy(c.constant_pool);
c.methods = new Method[methods.length];
- for(int i=0; i < methods.length; i++)
+ for (int i = 0; i < methods.length; i++)
c.methods[i] = methods[i].copy(c.constant_pool);
c.attributes = new Attribute[attributes.length];
- for(int i=0; i < attributes.length; i++)
+ for (int i = 0; i < attributes.length; i++)
c.attributes[i] = attributes[i].copy(c.constant_pool);
return c;
@@ -685,21 +751,25 @@
/** Equivalent to runtime "instanceof" operator.
*
- * @return true if this JavaClass is derived from teh super class
+ * @return true if this JavaClass is derived from the super class
+ * @throws ClassNotFoundException if superclasses or superinterfaces
+ * of this object can't be found
*/
- public final boolean instanceOf(JavaClass super_class) {
- if(this.equals(super_class))
+ public final boolean instanceOf(JavaClass super_class)
+ throws ClassNotFoundException {
+
+ if (this.equals(super_class))
return true;
JavaClass[] super_classes = getSuperClasses();
- for(int i=0; i < super_classes.length; i++) {
- if(super_classes[i].equals(super_class)) {
- return true;
+ for (int i = 0; i < super_classes.length; i++) {
+ if (super_classes[i].equals(super_class)) {
+ return true;
}
}
- if(super_class.isInterface()) {
+ if (super_class.isInterface()) {
return implementationOf(super_class);
}
@@ -707,22 +777,27 @@
}
/**
- * @return true, if clazz is an implementation of interface inter
+ * @return true, if this class is an implementation of interface inter
+ * @throws ClassNotFoundException if superclasses or superinterfaces
+ * of this class can't be found
*/
- public boolean implementationOf(JavaClass inter) {
- if(!inter.isInterface()) {
- throw new IllegalArgumentException(inter.getClassName() + " is no interface");
+ public boolean implementationOf(JavaClass inter)
+ throws ClassNotFoundException {
+
+ if (!inter.isInterface()) {
+ throw new IllegalArgumentException(
+ inter.getClassName() + " is no interface");
}
- if(this.equals(inter)) {
+ if (this.equals(inter)) {
return true;
}
JavaClass[] super_interfaces = getAllInterfaces();
- for(int i=0; i < super_interfaces.length; i++) {
- if(super_interfaces[i].equals(inter)) {
- return true;
+ for (int i = 0; i < super_interfaces.length; i++) {
+ if (super_interfaces[i].equals(inter)) {
+ return true;
}
}
@@ -732,31 +807,28 @@
/**
* @return the superclass for this JavaClass object, or null if this
* is java.lang.Object
+ * @throws ClassNotFoundException if the superclass can't be found
*/
- public JavaClass getSuperClass() {
- if("java.lang.Object".equals(getClassName())) {
+ public JavaClass getSuperClass() throws ClassNotFoundException {
+ if ("java.lang.Object".equals(getClassName())) {
return null;
}
- try {
- return repository.loadClass(getSuperclassName());
- } catch(ClassNotFoundException e) {
- System.err.println(e);
- return null;
- }
+ return repository.loadClass(getSuperclassName());
}
/**
* @return list of super classes of this class in ascending order, i.e.,
* java.lang.Object is always the last element
+ * @throws ClassNotFoundException if any of the superclasses can't be found
*/
- public JavaClass[] getSuperClasses() {
- JavaClass clazz = this;
- ClassVector vec = new ClassVector();
-
- for(clazz = clazz.getSuperClass(); clazz != null;
- clazz = clazz.getSuperClass())
- {
+ public JavaClass[] getSuperClasses() throws ClassNotFoundException {
+ JavaClass clazz = this;
+ ClassVector vec = new ClassVector();
+
+ for (clazz = clazz.getSuperClass();
+ clazz != null;
+ clazz = clazz.getSuperClass()) {
vec.addElement(clazz);
}
@@ -766,17 +838,12 @@
/**
* Get interfaces directly implemented by this JavaClass.
*/
- public JavaClass[] getInterfaces() {
- String[] interfaces = getInterfaceNames();
- JavaClass[] classes = new JavaClass[interfaces.length];
+ public JavaClass[] getInterfaces() throws ClassNotFoundException {
+ String[] interfaces = getInterfaceNames();
+ JavaClass[] classes = new JavaClass[interfaces.length];
- try {
- for(int i = 0; i < interfaces.length; i++) {
- classes[i] = repository.loadClass(interfaces[i]);
- }
- } catch(ClassNotFoundException e) {
- System.err.println(e);
- return null;
+ for (int i = 0; i < interfaces.length; i++) {
+ classes[i] = repository.loadClass(interfaces[i]);
}
return classes;
@@ -785,31 +852,66 @@
/**
* Get all interfaces implemented by this JavaClass (transitively).
*/
- public JavaClass[] getAllInterfaces() {
- ClassQueue queue = new ClassQueue();
- ClassVector vec = new ClassVector();
-
+ public JavaClass[] getAllInterfaces() throws ClassNotFoundException {
+ ClassQueue queue = new ClassQueue();
+ ClassVector vec = new ClassVector();
+
queue.enqueue(this);
-
- while(!queue.empty()) {
+
+ while (!queue.empty()) {
JavaClass clazz = queue.dequeue();
-
- JavaClass souper = clazz.getSuperClass();
+
+ JavaClass souper = clazz.getSuperClass();
JavaClass[] interfaces = clazz.getInterfaces();
-
- if(clazz.isInterface()) {
- vec.addElement(clazz);
+
+ if (clazz.isInterface()) {
+ vec.addElement(clazz);
} else {
- if(souper != null) {
- queue.enqueue(souper);
- }
+ if (souper != null) {
+ queue.enqueue(souper);
+ }
}
-
- for(int i = 0; i < interfaces.length; i++) {
- queue.enqueue(interfaces[i]);
+
+ for (int i = 0; i < interfaces.length; i++) {
+ queue.enqueue(interfaces[i]);
}
}
-
+
return vec.toArray();
+ }
+
+ /**
+ * @return Comparison strategy object
+ */
+ public static BCELComparator getComparator() {
+ return _cmp;
+ }
+
+ /**
+ * @param comparator Comparison strategy object
+ */
+ public static void setComparator(BCELComparator comparator) {
+ _cmp = comparator;
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default two JavaClass objects are said to be equal when
+ * their class names are equal.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return _cmp.equals(this, obj);
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy.
+ * By default return the hashcode of the class name.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return _cmp.hashCode(this);
}
}
1.4 +77 -23 jakarta-bcel/src/java/org/apache/bcel/classfile/Field.java
Index: Field.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/classfile/Field.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Field.java 8 Dec 2002 16:04:37 -0000 1.3
+++ Field.java 23 May 2003 07:50:52 -0000 1.4
@@ -53,8 +53,10 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
-import org.apache.bcel.Constants;
+import org.apache.bcel.Constants;
import org.apache.bcel.generic.Type;
+import org.apache.bcel.util.BCELComparator;
+
import java.io.*;
/**
@@ -62,13 +64,28 @@
* for a variable in the class. See JVM specification for details.
*
* @version $Id$
- * @author <A HREF="mailto:markus.dahm@berlin.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() {
+ public boolean equals(Object o1, Object o2) {
+ Field THIS = (Field)o1;
+ Field THAT = (Field)o2;
+
+ return THIS.getName().equals(THAT.getName())
+ && THIS.getSignature().equals(THAT.getSignature());
+ }
+
+ public int hashCode(Object o) {
+ Field THIS = (Field)o;
+ return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+ }
+ };
+
/**
- * Initialize from another object. Note that both objects use the same
- * references (shallow copy). Use clone() for a physical copy.
- */
+ * 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);
}
@@ -78,8 +95,7 @@
* @param file Input stream
*/
Field(DataInputStream file, ConstantPool constant_pool)
- throws IOException, ClassFormatException
- {
+ throws IOException, ClassFormatException {
super(file, constant_pool);
}
@@ -90,9 +106,12 @@
* @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)
- {
+ 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);
}
@@ -111,9 +130,9 @@
* @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];
+ for (int i = 0; i < attributes_count; i++)
+ if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE)
+ return (ConstantValue)attributes[i];
return null;
}
@@ -128,22 +147,22 @@
String name, signature, access; // Short cuts to constant pool
// Get names from constant pool
- access = Utility.accessToString(access_flags);
- access = access.equals("")? "" : (access + " ");
+ access = Utility.accessToString(access_flags);
+ access = access.equals("") ? "" : (access + " ");
signature = Utility.signatureToString(getSignature());
- name = getName();
+ name = getName();
- StringBuffer buf = new StringBuffer(access + signature + " " + name);
- ConstantValue cv = getConstantValue();
+ StringBuffer buf = new StringBuffer(access + signature + " " + name);
+ ConstantValue cv = getConstantValue();
- if(cv != null)
+ if (cv != null)
buf.append(" = " + cv);
- for(int i=0; i < attributes_count; i++) {
+ for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
- if(!(a instanceof ConstantValue))
- buf.append(" [" + a.toString() + "]");
+ if (!(a instanceof ConstantValue))
+ buf.append(" [" + a.toString() + "]");
}
return buf.toString();
@@ -161,5 +180,40 @@
*/
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);
}
}
1.6 +99 -33 jakarta-bcel/src/java/org/apache/bcel/classfile/Method.java
Index: Method.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/classfile/Method.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Method.java 8 Dec 2002 16:04:37 -0000 1.5
+++ Method.java 23 May 2003 07:50:52 -0000 1.6
@@ -53,9 +53,12 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
+import java.io.DataInputStream;
+import java.io.IOException;
+
import org.apache.bcel.Constants;
import org.apache.bcel.generic.Type;
-import java.io.*;
+import org.apache.bcel.util.BCELComparator;
/**
* This class represents the method info structure, i.e., the representation
@@ -63,14 +66,30 @@
* A method has access flags, a name, a signature and a number of attributes.
*
* @version $Id$
- * @author <A HREF="mailto:markus.dahm@berlin.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() {
+ public boolean equals(Object o1, Object o2) {
+ Method THIS = (Method)o1;
+ Method THAT = (Method)o2;
+
+ return THIS.getName().equals(THAT.getName())
+ && THIS.getSignature().equals(THAT.getSignature());
+ }
+
+ public int hashCode(Object o) {
+ Method THIS = (Method)o;
+ return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
+ }
+ };
+
/**
* Empty constructor, all attributes have to be defined via `setXXX'
* methods. Use at your own risk.
*/
- public Method() {}
+ public Method() {
+ }
/**
* Initialize from another object. Note that both objects use the same
@@ -87,8 +106,7 @@
* @throws ClassFormatException
*/
Method(DataInputStream file, ConstantPool constant_pool)
- throws IOException, ClassFormatException
- {
+ throws IOException, ClassFormatException {
super(file, constant_pool);
}
@@ -99,9 +117,12 @@
* @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)
- {
+ 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);
}
@@ -118,11 +139,11 @@
/**
* @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];
+ for (int i = 0; i < attributes_count; i++)
+ if (attributes[i] instanceof Code)
+ return (Code)attributes[i];
return null;
}
@@ -132,9 +153,9 @@
* 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];
+ for (int i = 0; i < attributes_count; i++)
+ if (attributes[i] instanceof ExceptionTable)
+ return (ExceptionTable)attributes[i];
return null;
}
@@ -145,7 +166,7 @@
public final LocalVariableTable getLocalVariableTable() {
Code code = getCode();
- if(code != null)
+ if (code != null)
return code.getLocalVariableTable();
else
return null;
@@ -157,7 +178,7 @@
public final LineNumberTable getLineNumberTable() {
Code code = getCode();
- if(code != null)
+ if (code != null)
return code.getLineNumberTable();
else
return null;
@@ -170,38 +191,48 @@
* @return String representation of the method.
*/
public final String toString() {
- ConstantUtf8 c;
- String name, signature, access; // Short cuts to constant pool
- StringBuffer buf;
+ 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);
+ c =
+ (ConstantUtf8)constant_pool.getConstant(
+ signature_index,
+ Constants.CONSTANT_Utf8);
signature = c.getBytes();
- c = (ConstantUtf8)constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
+ c =
+ (ConstantUtf8)constant_pool.getConstant(
+ name_index,
+ Constants.CONSTANT_Utf8);
name = c.getBytes();
- signature = Utility.methodSignatureToString(signature, name, access, true,
- getLocalVariableTable());
+ signature =
+ Utility.methodSignatureToString(
+ signature,
+ name,
+ access,
+ true,
+ getLocalVariableTable());
buf = new StringBuffer(signature);
- for(int i=0; i < attributes_count; i++) {
+ for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
- if(!((a instanceof Code) || (a instanceof ExceptionTable)))
- buf.append(" [" + a.toString() + "]");
+ if (!((a instanceof Code) || (a instanceof ExceptionTable)))
+ buf.append(" [" + a.toString() + "]");
}
ExceptionTable e = getExceptionTable();
- if(e != null) {
+ if (e != null) {
String str = e.toString();
- if(!str.equals(""))
- buf.append("\n\t\tthrows " + str);
+ if (!str.equals(""))
+ buf.append("\n\t\tthrows " + str);
}
-
+
return buf.toString();
}
@@ -224,5 +255,40 @@
*/
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);
}
}
1.4 +55 -3 jakarta-bcel/src/java/org/apache/bcel/classfile/Constant.java
Index: Constant.java
===================================================================
RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/classfile/Constant.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Constant.java 11 Jul 2002 19:39:04 -0000 1.3
+++ Constant.java 23 May 2003 07:50:52 -0000 1.4
@@ -55,6 +55,8 @@
*/
import org.apache.bcel.Constants;
+import org.apache.bcel.util.BCELComparator;
+
import java.io.*;
/**
@@ -63,9 +65,23 @@
* the JVM specification.
*
* @version $Id$
- * @author <A HREF="mailto:markus.dahm@berlin.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() {
+ public boolean equals(Object o1, Object o2) {
+ Constant THIS = (Constant)o1;
+ Constant THAT = (Constant)o2;
+
+ return THIS.toString().equals(THAT.toString());
+ }
+
+ public int hashCode(Object o) {
+ Constant THIS = (Constant)o;
+ return THIS.toString().hashCode();
+ }
+ };
+
/* In fact this tag is redundant since we can distinguish different
* `Constant' objects by their type, i.e., via `instanceof'. In some
* places we will use the tag for switch()es anyway.
@@ -144,5 +160,41 @@
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);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-dev-help@jakarta.apache.org