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:[email protected]">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:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">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:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">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:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">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:[email protected]">M. Dahm</A>
+ * @author <A HREF="mailto:[email protected]">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);
+ }
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.