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