    View Javadoc
    1   package org.apache.bcel.classfile;
    2
    3   /* ====================================================================
    4    * The Apache Software License, Version 1.1
    5    *
    6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
    7    * reserved.
    8    *
    9    * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   *
    16   * 2. Redistributions in binary form must reproduce the above copyright
    17   *    notice, this list of conditions and the following disclaimer in
    18   *    the documentation and/or other materials provided with the
    19   *    distribution.
    20   *
    21   * 3. The end-user documentation included with the redistribution,
    22   *    if any, must include the following acknowledgment:
    23   *       "This product includes software developed by the
    24   *        Apache Software Foundation (http://www.apache.org/)."
    25   *    Alternately, this acknowledgment may appear in the software itself,
    26   *    if and wherever such third-party acknowledgments normally appear.
    27   *
    28   * 4. The names "Apache" and "Apache Software Foundation" and
    29   *    "Apache BCEL" must not be used to endorse or promote products
    30   *    derived from this software without prior written permission. For
    31   *    written permission, please contact apache@apache.org.
    32   *
    33   * 5. Products derived from this software may not be called "Apache",
    34   *    "Apache BCEL", nor may "Apache" appear in their name, without
    35   *    prior written permission of the Apache Software Foundation.
    36   *
    37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
    41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    48   * SUCH DAMAGE.
    49   * ====================================================================
    50   *
    51   * This software consists of voluntary contributions made by many
    52   * individuals on behalf of the Apache Software Foundation.  For more
    53   * information on the Apache Software Foundation, please see
    54   * <http://www.apache.org/>;.
    55   */
    56
    57  import  org.apache.bcel.Constants;
    58  import  org.apache.bcel.util.SyntheticRepository;
    59  import  org.apache.bcel.util.ClassVector;
    60  import  org.apache.bcel.util.ClassQueue;
    61  import  org.apache.bcel.generic.Type;
    62
    63  import  java.io.*;
    64  import  java.util.StringTokenizer;
    65
    66  /***
    67   * Represents a Java class, i.e., the data structures, constant pool,
    68   * fields, methods and commands contained in a Java .class file.
    69   * See <a href="ftp://java.sun.com/docs/specs/">JVM
    70   * specification</a> for details.
    71
    72   * The intent of this class is to represent a parsed or otherwise existing
    73   * class file.  Those interested in programatically generating classes
    74   * should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
    75
    76   * @version $Id: JavaClass.java,v 1.13 2002/07/11 19:39:04 mdahm Exp $
    77   * @see org.apache.bcel.generic.ClassGen
    78   * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
    79   */
    80  public class JavaClass extends AccessFlags implements Cloneable, Node {
    81    private String       file_name;
    82    private String       package_name/package-summary.html">b> String       package_name;
    83    private String       source_file_name = "<Unknown>";
    84    private int          class_name_index;
    85    private int          superclass_name_index;
    86    private String       class_name;
    87    private String       superclass_name;
    88    private int          major, minor;  // Compiler version
    89    private ConstantPool constant_pool; // Constant pool
    90    private int[]        interfaces;    // implemented interfaces
    91    private String[]     interface_names;
    92    private Field[]      fields;        // Fields, i.e., variables of class
    93    private Method[]     methods;       // methods defined in the class
    94    private Attribute[]  attributes;    // attributes defined in the class
    95    private byte         source = HEAP; // Generated in memory
    96
    97    public static final byte HEAP = 1;
    98    public static final byte FILE = 2;
    99    public static final byte ZIP  = 3;
    100
    101   static boolean debug = false; // Debugging on/off
    102   static char    sep   = '/';   // directory separator
    103
    104   /***
    105    * In cases where we go ahead and create something,
    106    * use the default SyntheticRepository, because we
    107    * don't know any better.
    108    */
    109   private transient org.apache.bcel.util.Repository repository =
    110     SyntheticRepository.getInstance();
    111
    112   /***
    113    * Constructor gets all contents as arguments.
    114    *
    115    * @param class_name_index Index into constant pool referencing a
    116    * ConstantClass that represents this class.
    117    * @param superclass_name_index Index into constant pool referencing a
    118    * ConstantClass that represents this class's superclass.
    119    * @param file_name File name
    120    * @param major Major compiler version
    121    * @param minor Minor compiler version
    122    * @param access_flags Access rights defined by bit flags
    123    * @param constant_pool Array of constants
    124    * @param interfaces Implemented interfaces
    125    * @param fields Class fields
    126    * @param methods Class methods
    127    * @param attributes Class attributes
    128    * @param source Read from file or generated in memory?
    129    */
    130   public JavaClass(int        class_name_index,
    131 		   int        superclass_name_index,
    132 		   String     file_name,
    133 		   int        major,
    134 		   int        minor,
    135 		   int        access_flags,
    136 		   ConstantPool constant_pool,
    137 		   int[]      interfaces,
    138 		   Field[]      fields,
    139 		   Method[]     methods,
    140 		   Attribute[]  attributes,
    141 		   byte          source)
    142   {
    143     if(interfaces == null) // Allowed for backward compatibility
    144       interfaces = new int[0];
    145     if(attributes == null)
    146       this.attributes = new Attribute[0];
    147     if(fields == null)
    148       fields = new Field[0];
    149     if(methods == null)
    150       methods = new Method[0];
    151
    152     this.class_name_index      = class_name_index;
    153     this.superclass_name_index = superclass_name_index;
    154     this.file_name             = file_name;
    155     this.major                 = major;
    156     this.minor                 = minor;
    157     this.access_flags          = access_flags;
    158     this.constant_pool         = constant_pool;
    159     this.interfaces            = interfaces;
    160     this.fields                = fields;
    161     this.methods               = methods;
    162     this.attributes            = attributes;
    163     this.source                = source;
    164
    165     // Get source file name if available
    166     for(int i=0; i < attributes.length; i++) {
    167       if(attributes[i] instanceof SourceFile) {
    168 	source_file_name = ((SourceFile)attributes[i]).getSourceFileName();
    169 	break;
    170       }
    171     }
    172
    173     /* According to the specification the following entries must be of type
    174      * `ConstantClass' but we check that anyway via the
    175      * `ConstPool.getConstant' method.
    176      */
    177     class_name = constant_pool.getConstantString(class_name_index,
    178 						 Constants.CONSTANT_Class);
    179     class_name = Utility.compactClassName(class_name, false);
    180
    181     int index = class_name.lastIndexOf('.');
    182     if(index < 0)
    183       package>_name = "";
    184     else
    185       package>_name = class_name.substring(0, index);
    186
    187     if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object
    188       superclass_name = constant_pool.getConstantString(superclass_name_index,
    189 							Constants.CONSTANT_Class);
    190       superclass_name = Utility.compactClassName(superclass_name, false);
    191     }
    192     else
    193       superclass_name = "java.lang.Object";
    194
    195     interface_names = new String[interfaces.length];
    196     for(int i=0; i < interfaces.length; i++) {
    197       String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
    198       interface_names[i] = Utility.compactClassName(str, false);
    199     }
    200   }
    201
    202   /***
    203    * Constructor gets all contents as arguments.
    204    *
    205    * @param class_name_index Class name
    206    * @param superclass_name_index Superclass name
    207    * @param file_name File name
    208    * @param major Major compiler version
    209    * @param minor Minor compiler version
    210    * @param access_flags Access rights defined by bit flags
    211    * @param constant_pool Array of constants
    212    * @param interfaces Implemented interfaces
    213    * @param fields Class fields
    214    * @param methods Class methods
    215    * @param attributes Class attributes
    216    */
    217   public JavaClass(int        class_name_index,
    218 		   int        superclass_name_index,
    219 		   String     file_name,
    220 		   int        major,
    221 		   int        minor,
    222 		   int        access_flags,
    223 		   ConstantPool constant_pool,
    224 		   int[]      interfaces,
    225 		   Field[]      fields,
    226 		   Method[]     methods,
    227 		   Attribute[]  attributes) {
    228     this(class_name_index, superclass_name_index, file_name, major, minor, access_flags,
    229 	 constant_pool, interfaces, fields, methods, attributes, HEAP);
    230   }
    231
    232
    233   /***
    234    * Called by objects that are traversing the nodes of the tree implicitely
    235    * defined by the contents of a Java class. I.e., the hierarchy of methods,
    236    * fields, attributes, etc. spawns a tree of objects.
    237    *
    238    * @param v Visitor object
    239    */
    240   public void accept(Visitor v) {
    241     v.visitJavaClass(this);
    242   }
    243
    244   /* Print debug information depending on `JavaClass.debug'
    245    */
    246   static final void Debug(String str) {
    247     if(debug)
    248       System.out.println(str);
    249   }
    250
    251   /***
    252    * Dump class to a file.
    253    *
    254    * @param file Output file
    255    * @throws IOException
    256    */
    257   public void dump(File file) throws IOException
    258   {
    259     String parent = file.getParent();
    260
    261     if(parent != null) {
    262       File dir = new File(parent);
    263
    264       if(dir != null)
    265 	dir.mkdirs();
    266     }
    267
    268     dump(new DataOutputStream(new FileOutputStream(file)));
    269   }
    270
    271   /***
    272    * Dump class to a file named file_name.
    273    *
    274    * @param file_name Output file name
    275    * @exception IOException
    276    */
    277   public void dump(String file_name) throws IOException
    278   {
    279     dump(new File(file_name));
    280   }
    281
    282   /***
    283    * @return class in binary format
    284    */
    285   public byte[] getBytes() {
    286     ByteArrayOutputStream s  = new ByteArrayOutputStream();
    287     DataOutputStream      ds = new DataOutputStream(s);
    288
    289     try {
    290       dump(ds);
    291     } catch(IOException e) {
    292       e.printStackTrace();
    293     } finally {
    294       try { ds.close(); } catch(IOException e2) { e2.printStackTrace(); }
    295     }
    296
    297     return s.toByteArray();
    298   }
    299
    300   /***
    301    * Dump Java class to output stream in binary format.
    302    *
    303    * @param file Output stream
    304    * @exception IOException
    305    */
    306   public void dump(OutputStream file) throws IOException {
    307     dump(new DataOutputStream(file));
    308   }
    309
    310   /***
    311    * Dump Java class to output stream in binary format.
    312    *
    313    * @param file Output stream
    314    * @exception IOException
    315    */
    316   public void dump(DataOutputStream file) throws IOException
    317   {
    318     file.writeInt(0xcafebabe);
    319     file.writeShort(minor);
    320     file.writeShort(major);
    321
    322     constant_pool.dump(file);
    323
    324     file.writeShort(access_flags);
    325     file.writeShort(class_name_index);
    326     file.writeShort(superclass_name_index);
    327
    328     file.writeShort(interfaces.length);
    329     for(int i=0; i < interfaces.length; i++)
    330       file.writeShort(interfaces[i]);
    331
    332     file.writeShort(fields.length);
    333     for(int i=0; i < fields.length; i++)
    334       fields[i].dump(file);
    335
    336     file.writeShort(methods.length);
    337     for(int i=0; i < methods.length; i++)
    338       methods[i].dump(file);
    339
    340     if(attributes != null) {
    341       file.writeShort(attributes.length);
    342       for(int i=0; i < attributes.length; i++)
    343 	attributes[i].dump(file);
    344     }
    345     else
    346       file.writeShort(0);
    347
    348     file.close();
    349   }
    350
    351   /***
    352    * @return Attributes of the class.
    353    */
    354   public Attribute[] getAttributes() { return attributes; }
    355
    356   /***
    357    * @return Class name.
    358    */
    359   public String getClassName()       { return class_name; }
    360
    361   /***
    362    * @return Package name.
    363    */
    364   public String getPackageName()       { return package_name; }
    365
    366   /***
    367    * @return Class name index.
    368    */
    369   public int getClassNameIndex()   { return class_name_index; }
    370
    371   /***
    372    * @return Constant pool.
    373    */
    374   public ConstantPool getConstantPool() { return constant_pool; }
    375
    376   /***
    377    * @return Fields, i.e., variables of the class. Like the JVM spec
    378    * mandates for the classfile format, these fields are those specific to
    379    * this class, and not those of the superclass or superinterfaces.
    380    */
    381   public Field[] getFields()         { return fields; }
    382
    383   /***
    384    * @return File name of class, aka SourceFile attribute value
    385    */
    386   public String getFileName()        { return file_name; }
    387
    388   /***
    389    * @return Names of implemented interfaces.
    390    */
    391   public String[] getInterfaceNames()  { return interface_names; }
    392
    393   /***
    394    * @return Indices in constant pool of implemented interfaces.
    395    */
    396   public int[] getInterfaceIndices()     { return interfaces; }
    397
    398   /***
    399    * @return Major number of class file version.
    400    */
    401   public int  getMajor()           { return major; }
    402
    403   /***
    404    * @return Methods of the class.
    405    */
    406   public Method[] getMethods()       { return methods; }
    407
    408   /***
    409    * @return A org.apache.bcel.classfile.Method corresponding to
    410    * java.lang.reflect.Method if any
    411    */
    412   public Method getMethod(java.lang.reflect.Method m) {
    413     for(int i = 0; i < methods.length; i++) {
    414       Method method = methods[i];
    415
    416       if(m.getName().equals(method.getName()) &&
    417 	 (m.getModifiers() == method.getModifiers()) &&
    418 	 Type.getSignature(m).equals(method.getSignature())) {
    419 	return method;
    420       }
    421     }
    422
    423     return null;
    424   }
    425
    426   /***
    427    * @return Minor number of class file version.
    428    */
    429   public int  getMinor()           { return minor; }
    430
    431   /***
    432    * @return sbsolute path to file where this class was read from
    433    */
    434   public String getSourceFileName()  { return source_file_name; }
    435
    436   /***
    437    * @return Superclass name.
    438    */
    439   public String getSuperclassName()  { return superclass_name; }
    440
    441   /***
    442    * @return Class name index.
    443    */
    444   public int getSuperclassNameIndex() { return superclass_name_index; }
    445
    446   static {
    447     // Debugging ... on/off
    448     String debug = System.getProperty("JavaClass.debug");
    449
    450     if(debug != null)
    451       JavaClass.debug = new Boolean(debug).booleanValue();
    452
    453     // Get path separator either / or \ usually
    454     String sep = System.getProperty("file.separator");
    455
    456     if(sep != null)
    457       try {
    458 	JavaClass.sep = sep.charAt(0);
    459       } catch(StringIndexOutOfBoundsException e) {} // Never reached
    460   }
    461
    462   /***
    463    * @param attributes .
    464    */
    465   public void setAttributes(Attribute[] attributes) {
    466     this.attributes = attributes;
    467   }
    468
    469   /***
    470    * @param class_name .
    471    */
    472   public void setClassName(String class_name) {
    473     this.class_name = class_name;
    474   }
    475
    476   /***
    477    * @param class_name_index .
    478    */
    479   public void setClassNameIndex(int class_name_index) {
    480     this.class_name_index = class_name_index;
    481   }
    482
    483   /***
    484    * @param constant_pool .
    485    */
    486   public void setConstantPool(ConstantPool constant_pool) {
    487     this.constant_pool = constant_pool;
    488   }
    489
    490   /***
    491    * @param fields .
    492    */
    493   public void setFields(Field[] fields) {
    494     this.fields = fields;
    495   }
    496
    497   /***
    498    * Set File name of class, aka SourceFile attribute value
    499    */
    500   public void setFileName(String file_name) {
    501     this.file_name = file_name;
    502   }
    503
    504   /***
    505    * @param interface_names .
    506    */
    507   public void setInterfaceNames(String[] interface_names) {
    508     this.interface_names = interface_names;
    509   }
    510
    511   /***
    512    * @param interfaces .
    513    */
    514   public void setInterfaces(int[] interfaces) {
    515     this.interfaces = interfaces;
    516   }
    517
    518   /***
    519    * @param major .
    520    */
    521   public void setMajor(int major) {
    522     this.major = major;
    523   }
    524
    525   /***
    526    * @param methods .
    527    */
    528   public void setMethods(Method[] methods) {
    529     this.methods = methods;
    530   }
    531
    532   /***
    533    * @param minor .
    534    */
    535   public void setMinor(int minor) {
    536     this.minor = minor;
    537   }
    538
    539   /***
    540    * Set absolute path to file this class was read from.
    541    */
    542   public void setSourceFileName(String source_file_name) {
    543     this.source_file_name = source_file_name;
    544   }
    545
    546   /***
    547    * @param superclass_name .
    548    */
    549   public void setSuperclassName(String superclass_name) {
    550     this.superclass_name = superclass_name;
    551   }
    552
    553   /***
    554    * @param superclass_name_index .
    555    */
    556   public void setSuperclassNameIndex(int superclass_name_index) {
    557     this.superclass_name_index = superclass_name_index;
    558   }
    559
    560   /***
    561    * @return String representing class contents.
    562    */
    563   public String toString() {
    564     String access = Utility.accessToString(access_flags, true);
    565     access = access.equals("")? "" : (access + " ");
    566
    567     StringBuffer buf = new StringBuffer(access +
    568 					Utility.classOrInterface(access_flags) +
    569 					" " +
    570 					class_name + " extends " +
    571 					Utility.compactClassName(superclass_name,
    572 								 false) + '\n');
    573     int size = interfaces.length;
    574
    575     if(size > 0) {
    576       buf.append("implements\t\t");
    577
    578       for(int i=0; i < size; i++) {
    579 	buf.append(interface_names[i]);
    580 	if(i < size - 1)
    581 	  buf.append(", ");
    582       }
    583
    584       buf.append('\n');
    585     }
    586
    587     buf.append("filename\t\t" + file_name + '\n');
    588     buf.append("compiled from\t\t" + source_file_name + '\n');
    589     buf.append("compiler version\t" + major + "." + minor + '\n');
    590     buf.append("access flags\t\t" + access_flags + '\n');
    591     buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n");
    592     buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n");
    593
    594     if(attributes.length > 0) {
    595       buf.append("\nAttribute(s):\n");
    596       for(int i=0; i < attributes.length; i++)
    597 	buf.append(indent(attributes[i]));
    598     }
    599
    600     if(fields.length > 0) {
    601       buf.append("\n" + fields.length + " fields:\n");
    602       for(int i=0; i < fields.length; i++)
    603 	buf.append("\t" + fields[i] + '\n');
    604     }
    605
    606     if(methods.length > 0) {
    607       buf.append("\n" + methods.length + " methods:\n");
    608       for(int i=0; i < methods.length; i++)
    609 	buf.append("\t" + methods[i] + '\n');
    610     }
    611
    612     return buf.toString();
    613   }
    614
    615   private static final String indent(Object obj) {
    616     StringTokenizer tok = new StringTokenizer(obj.toString(), "\n");
    617     StringBuffer buf = new StringBuffer();
    618
    619     while(tok.hasMoreTokens())
    620       buf.append("\t" + tok.nextToken() + "\n");
    621
    622     return buf.toString();
    623   }
    624
    625   /***
    626    * @return deep copy of this class
    627    */
    628   public JavaClass copy() {
    629     JavaClass c = null;
    630
    631     try {
    632       c = (JavaClass)clone();
    633     } catch(CloneNotSupportedException e) {}
    634
    635     c.constant_pool   = constant_pool.copy();
    636     c.interfaces      = (int[])interfaces.clone();
    637     c.interface_names = (String[])interface_names.clone();
    638
    639     c.fields = new Field[fields.length];
    640     for(int i=0; i < fields.length; i++)
    641       c.fields[i] = fields[i].copy(c.constant_pool);
    642
    643     c.methods = new Method[methods.length];
    644     for(int i=0; i < methods.length; i++)
    645       c.methods[i] = methods[i].copy(c.constant_pool);
    646
    647     c.attributes = new Attribute[attributes.length];
    648     for(int i=0; i < attributes.length; i++)
    649       c.attributes[i] = attributes[i].copy(c.constant_pool);
    650
    651     return c;
    652   }
    653
    654   public final boolean isSuper() {
    655     return (access_flags & Constants.ACC_SUPER) != 0;
    656   }
    657
    658   public final boolean isClass() {
    659     return (access_flags & Constants.ACC_INTERFACE) == 0;
    660   }
    661
    662   /*** @return returns either HEAP (generated), FILE, or ZIP
    663    */
    664   public final byte getSource() {
    665     return source;
    666   }
    667
    668   /********************** New repository functionality *********************/
    669
    670   /***
    671    * Gets the ClassRepository which holds its definition. By default
    672    * this is the same as SyntheticRepository.getInstance();
    673    */
    674   public org.apache.bcel.util.Repository getRepository() {
    675     return repository;
    676   }
    677
    678   /***
    679    * Sets the ClassRepository which loaded the JavaClass.
    680    * Should be called immediately after parsing is done.
    681    */
    682   public void setRepository(org.apache.bcel.util.Repository repository) {
    683     this.repository = repository;
    684   }
    685
    686   /*** Equivalent to runtime "instanceof" operator.
    687    *
    688    * @return true if this JavaClass is derived from teh super class
    689    */
    690   public final boolean instanceOf(JavaClass super_class) {
    691     if(this.equals(super_class))
    692       return true;
    693
    694     JavaClass[] super_classes = getSuperClasses();
    695
    696     for(int i=0; i < super_classes.length; i++) {
    697       if(super_classes[i].equals(super_class)) {
    698 	return true;
    699       }
    700     }
    701
    702     if(super_class.isInterface()) {
    703       return implementationOf(super_class);
    704     }
    705
    706     return false;
    707   }
    708
    709   /***
    710    * @return true, if clazz is an implementation of interface inter
    711    */
    712   public boolean implementationOf(JavaClass inter) {
    713     if(!inter.isInterface()) {
    714       throw new IllegalArgumentException(inter.getClassName() + " is no interface");
    715     }
    716
    717     if(this.equals(inter)) {
    718       return true;
    719     }
    720
    721     JavaClass[] super_interfaces = getAllInterfaces();
    722
    723     for(int i=0; i < super_interfaces.length; i++) {
    724       if(super_interfaces[i].equals(inter)) {
    725 	return true;
    726       }
    727     }
    728
    729     return false;
    730   }
    731
    732   /***
    733    * @return the superclass for this JavaClass object, or null if this
    734    * is java.lang.Object
    735    */
    736   public JavaClass getSuperClass() {
    737     if("java.lang.Object".equals(getClassName())) {
    738       return null;
    739     }
    740
    741     try {
    742       return repository.loadClass(getSuperclassName());
    743     } catch(ClassNotFoundException e) {
    744       System.err.println(e);
    745       return null;
    746     }
    747   }
    748
    749   /***
    750    * @return list of super classes of this class in ascending order, i.e.,
    751    * java.lang.Object is always the last element
    752    */
    753   public JavaClass[] getSuperClasses() {
    754     JavaClass   clazz = this;
    755     ClassVector vec   = new ClassVector();
    756
    757     for(clazz = clazz.getSuperClass(); clazz != null;
    758 	clazz = clazz.getSuperClass())
    759     {
    760       vec.addElement(clazz);
    761     }
    762
    763     return vec.toArray();
    764   }
    765
    766   /***
    767    * Get interfaces directly implemented by this JavaClass.
    768    */
    769   public JavaClass[] getInterfaces() {
    770     String[]    interfaces = getInterfaceNames();
    771     JavaClass[] classes    = new JavaClass[interfaces.length];
    772
    773     try {
    774       for(int i = 0; i < interfaces.length; i++) {
    775 	classes[i] = repository.loadClass(interfaces[i]);
    776       }
    777     } catch(ClassNotFoundException e) {
    778       System.err.println(e);
    779       return null;
    780     }
    781
    782     return classes;
    783   }
    784
    785   /***
    786    * Get all interfaces implemented by this JavaClass (transitively).
    787    */
    788   public JavaClass[] getAllInterfaces() {
    789     ClassQueue  queue = new ClassQueue();
    790     ClassVector vec   = new ClassVector();
    791
    792     queue.enqueue(this);
    793
    794     while(!queue.empty()) {
    795       JavaClass clazz = queue.dequeue();
    796
    797       JavaClass   souper     = clazz.getSuperClass();
    798       JavaClass[] interfaces = clazz.getInterfaces();
    799
    800       if(clazz.isInterface()) {
    801 	vec.addElement(clazz);
    802       } else {
    803 	if(souper != null) {
    804 	  queue.enqueue(souper);
    805 	}
    806       }
    807
    808       for(int i = 0; i < interfaces.length; i++) {
    809 	queue.enqueue(interfaces[i]);
    810       }
    811     }
    812
    813     return vec.toArray();
    814   }
    815 }

This page was automatically generated by Maven