KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bcel > classfile > JavaClass


1 /*
2  * Copyright 2000-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.bcel.classfile;
18
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.DataOutputStream JavaDoc;
21 import java.io.File JavaDoc;
22 import java.io.FileOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.TreeSet JavaDoc;
30 import org.apache.bcel.Constants;
31 import org.apache.bcel.generic.Type;
32 import org.apache.bcel.util.BCELComparator;
33 import org.apache.bcel.util.ClassQueue;
34 import org.apache.bcel.util.SyntheticRepository;
35
36 /**
37  * Represents a Java class, i.e., the data structures, constant pool,
38  * fields, methods and commands contained in a Java .class file.
39  * See <a HREF="ftp://java.sun.com/docs/specs/">JVM specification</a> for details.
40  * The intent of this class is to represent a parsed or otherwise existing
41  * class file. Those interested in programatically generating classes
42  * should see the <a HREF="../generic/ClassGen.html">ClassGen</a> class.
43
44  * @version $Id: JavaClass.java 386056 2006-03-15 11:31:56Z tcurdt $
45  * @see org.apache.bcel.generic.ClassGen
46  * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
47  */

48 public class JavaClass extends AccessFlags implements Cloneable JavaDoc, Node, Comparable JavaDoc {
49
50     private String JavaDoc file_name;
51     private String JavaDoc package_name;
52     private String JavaDoc source_file_name = "<Unknown>";
53     private int class_name_index;
54     private int superclass_name_index;
55     private String JavaDoc class_name;
56     private String JavaDoc superclass_name;
57     private int major, minor; // Compiler version
58
private ConstantPool constant_pool; // Constant pool
59
private int[] interfaces; // implemented interfaces
60
private String JavaDoc[] interface_names;
61     private Field[] fields; // Fields, i.e., variables of class
62
private Method[] methods; // methods defined in the class
63
private Attribute[] attributes; // attributes defined in the class
64
private byte source = HEAP; // Generated in memory
65
public static final byte HEAP = 1;
66     public static final byte FILE = 2;
67     public static final byte ZIP = 3;
68     static boolean debug = false; // Debugging on/off
69
static char sep = '/'; // directory separator
70
private static BCELComparator _cmp = new BCELComparator() {
71
72         public boolean equals( Object JavaDoc o1, Object JavaDoc o2 ) {
73             JavaClass THIS = (JavaClass) o1;
74             JavaClass THAT = (JavaClass) o2;
75             return THIS.getClassName().equals(THAT.getClassName());
76         }
77
78
79         public int hashCode( Object JavaDoc o ) {
80             JavaClass THIS = (JavaClass) o;
81             return THIS.getClassName().hashCode();
82         }
83     };
84     /**
85      * In cases where we go ahead and create something,
86      * use the default SyntheticRepository, because we
87      * don't know any better.
88      */

89     private transient org.apache.bcel.util.Repository repository = SyntheticRepository
90             .getInstance();
91
92
93     /**
94      * Constructor gets all contents as arguments.
95      *
96      * @param class_name_index Index into constant pool referencing a
97      * ConstantClass that represents this class.
98      * @param superclass_name_index Index into constant pool referencing a
99      * ConstantClass that represents this class's superclass.
100      * @param file_name File name
101      * @param major Major compiler version
102      * @param minor Minor compiler version
103      * @param access_flags Access rights defined by bit flags
104      * @param constant_pool Array of constants
105      * @param interfaces Implemented interfaces
106      * @param fields Class fields
107      * @param methods Class methods
108      * @param attributes Class attributes
109      * @param source Read from file or generated in memory?
110      */

111     public JavaClass(int class_name_index, int superclass_name_index, String JavaDoc file_name, int major,
112             int minor, int access_flags, ConstantPool constant_pool, int[] interfaces,
113             Field[] fields, Method[] methods, Attribute[] attributes, byte source) {
114         if (interfaces == null) {
115             interfaces = new int[0];
116         }
117         if (attributes == null) {
118             attributes = new Attribute[0];
119         }
120         if (fields == null) {
121             fields = new Field[0];
122         }
123         if (methods == null) {
124             methods = new Method[0];
125         }
126         this.class_name_index = class_name_index;
127         this.superclass_name_index = superclass_name_index;
128         this.file_name = file_name;
129         this.major = major;
130         this.minor = minor;
131         this.access_flags = access_flags;
132         this.constant_pool = constant_pool;
133         this.interfaces = interfaces;
134         this.fields = fields;
135         this.methods = methods;
136         this.attributes = attributes;
137         this.source = source;
138         // Get source file name if available
139
for (int i = 0; i < attributes.length; i++) {
140             if (attributes[i] instanceof SourceFile) {
141                 source_file_name = ((SourceFile) attributes[i]).getSourceFileName();
142                 break;
143             }
144         }
145         /* According to the specification the following entries must be of type
146          * `ConstantClass' but we check that anyway via the
147          * `ConstPool.getConstant' method.
148          */

149         class_name = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class);
150         class_name = Utility.compactClassName(class_name, false);
151         int index = class_name.lastIndexOf('.');
152         if (index < 0) {
153             package_name = "";
154         } else {
155             package_name = class_name.substring(0, index);
156         }
157         if (superclass_name_index > 0) {
158             // May be zero -> class is java.lang.Object
159
superclass_name = constant_pool.getConstantString(superclass_name_index,
160                     Constants.CONSTANT_Class);
161             superclass_name = Utility.compactClassName(superclass_name, false);
162         } else {
163             superclass_name = "java.lang.Object";
164         }
165         interface_names = new String JavaDoc[interfaces.length];
166         for (int i = 0; i < interfaces.length; i++) {
167             String JavaDoc str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
168             interface_names[i] = Utility.compactClassName(str, false);
169         }
170     }
171
172
173     /**
174      * Constructor gets all contents as arguments.
175      *
176      * @param class_name_index Class name
177      * @param superclass_name_index Superclass name
178      * @param file_name File name
179      * @param major Major compiler version
180      * @param minor Minor compiler version
181      * @param access_flags Access rights defined by bit flags
182      * @param constant_pool Array of constants
183      * @param interfaces Implemented interfaces
184      * @param fields Class fields
185      * @param methods Class methods
186      * @param attributes Class attributes
187      */

188     public JavaClass(int class_name_index, int superclass_name_index, String JavaDoc file_name, int major,
189             int minor, int access_flags, ConstantPool constant_pool, int[] interfaces,
190             Field[] fields, Method[] methods, Attribute[] attributes) {
191         this(class_name_index, superclass_name_index, file_name, major, minor, access_flags,
192                 constant_pool, interfaces, fields, methods, attributes, HEAP);
193     }
194
195
196     /**
197      * Called by objects that are traversing the nodes of the tree implicitely
198      * defined by the contents of a Java class. I.e., the hierarchy of methods,
199      * fields, attributes, etc. spawns a tree of objects.
200      *
201      * @param v Visitor object
202      */

203     public void accept( Visitor v ) {
204         v.visitJavaClass(this);
205     }
206
207
208     /* Print debug information depending on `JavaClass.debug'
209      */

210     static final void Debug( String JavaDoc str ) {
211         if (debug) {
212             System.out.println(str);
213         }
214     }
215
216
217     /**
218      * Dump class to a file.
219      *
220      * @param file Output file
221      * @throws IOException
222      */

223     public void dump( File JavaDoc file ) throws IOException JavaDoc {
224         String JavaDoc parent = file.getParent();
225         if (parent != null) {
226             File JavaDoc dir = new File JavaDoc(parent);
227             dir.mkdirs();
228         }
229         DataOutputStream JavaDoc dos = null;
230         try {
231             dos = new DataOutputStream JavaDoc(new FileOutputStream JavaDoc(file));
232             dump(dos);
233         } finally {
234             if (dos != null) {
235                 dos.close();
236             }
237         }
238     }
239
240
241     /**
242      * Dump class to a file named file_name.
243      *
244      * @param _file_name Output file name
245      * @exception IOException
246      */

247     public void dump( String JavaDoc _file_name ) throws IOException JavaDoc {
248         dump(new File JavaDoc(_file_name));
249     }
250
251
252     /**
253      * @return class in binary format
254      */

255     public byte[] getBytes() {
256         ByteArrayOutputStream JavaDoc s = new ByteArrayOutputStream JavaDoc();
257         DataOutputStream JavaDoc ds = new DataOutputStream JavaDoc(s);
258         try {
259             dump(ds);
260         } catch (IOException JavaDoc e) {
261             e.printStackTrace();
262         } finally {
263             try {
264                 ds.close();
265             } catch (IOException JavaDoc e2) {
266                 e2.printStackTrace();
267             }
268         }
269         return s.toByteArray();
270     }
271
272
273     /**
274      * Dump Java class to output stream in binary format.
275      *
276      * @param file Output stream
277      * @exception IOException
278      */

279     public void dump( OutputStream JavaDoc file ) throws IOException JavaDoc {
280         dump(new DataOutputStream JavaDoc(file));
281     }
282
283
284     /**
285      * Dump Java class to output stream in binary format.
286      *
287      * @param file Output stream
288      * @exception IOException
289      */

290     public void dump( DataOutputStream JavaDoc file ) throws IOException JavaDoc {
291         file.writeInt(0xcafebabe);
292         file.writeShort(minor);
293         file.writeShort(major);
294         constant_pool.dump(file);
295         file.writeShort(access_flags);
296         file.writeShort(class_name_index);
297         file.writeShort(superclass_name_index);
298         file.writeShort(interfaces.length);
299         for (int i = 0; i < interfaces.length; i++) {
300             file.writeShort(interfaces[i]);
301         }
302         file.writeShort(fields.length);
303         for (int i = 0; i < fields.length; i++) {
304             fields[i].dump(file);
305         }
306         file.writeShort(methods.length);
307         for (int i = 0; i < methods.length; i++) {
308             methods[i].dump(file);
309         }
310         if (attributes != null) {
311             file.writeShort(attributes.length);
312             for (int i = 0; i < attributes.length; i++) {
313                 attributes[i].dump(file);
314             }
315         } else {
316             file.writeShort(0);
317         }
318         file.flush();
319     }
320
321
322     /**
323      * @return Attributes of the class.
324      */

325     public Attribute[] getAttributes() {
326         return attributes;
327     }
328
329
330     /**
331      * @return Class name.
332      */

333     public String JavaDoc getClassName() {
334         return class_name;
335     }
336
337
338     /**
339      * @return Package name.
340      */

341     public String JavaDoc getPackageName() {
342         return package_name;
343     }
344
345
346     /**
347      * @return Class name index.
348      */

349     public int getClassNameIndex() {
350         return class_name_index;
351     }
352
353
354     /**
355      * @return Constant pool.
356      */

357     public ConstantPool getConstantPool() {
358         return constant_pool;
359     }
360
361
362     /**
363      * @return Fields, i.e., variables of the class. Like the JVM spec
364      * mandates for the classfile format, these fields are those specific to
365      * this class, and not those of the superclass or superinterfaces.
366      */

367     public Field[] getFields() {
368         return fields;
369     }
370
371
372     /**
373      * @return File name of class, aka SourceFile attribute value
374      */

375     public String JavaDoc getFileName() {
376         return file_name;
377     }
378
379
380     /**
381      * @return Names of implemented interfaces.
382      */

383     public String JavaDoc[] getInterfaceNames() {
384         return interface_names;
385     }
386
387
388     /**
389      * @return Indices in constant pool of implemented interfaces.
390      */

391     public int[] getInterfaceIndices() {
392         return interfaces;
393     }
394
395
396     /**
397      * @return Major number of class file version.
398      */

399     public int getMajor() {
400         return major;
401     }
402
403
404     /**
405      * @return Methods of the class.
406      */

407     public Method[] getMethods() {
408         return methods;
409     }
410
411
412     /**
413      * @return A org.apache.bcel.classfile.Method corresponding to
414      * java.lang.reflect.Method if any
415      */

416     public Method getMethod( java.lang.reflect.Method JavaDoc m ) {
417         for (int i = 0; i < methods.length; i++) {
418             Method method = methods[i];
419             if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers())
420                     && Type.getSignature(m).equals(method.getSignature())) {
421                 return method;
422             }
423         }
424         return null;
425     }
426
427
428     /**
429      * @return Minor number of class file version.
430      */

431     public int getMinor() {
432         return minor;
433     }
434
435
436     /**
437      * @return sbsolute path to file where this class was read from
438      */

439     public String JavaDoc getSourceFileName() {
440         return source_file_name;
441     }
442
443
444     /**
445      * @return Superclass name.
446      */

447     public String JavaDoc getSuperclassName() {
448         return superclass_name;
449     }
450
451
452     /**
453      * @return Class name index.
454      */

455     public int getSuperclassNameIndex() {
456         return superclass_name_index;
457     }
458
459     static {
460         // Debugging ... on/off
461
debug = Boolean.getBoolean("JavaClass.debug");
462         // Get path separator either / or \ usually
463
String JavaDoc _sep = System.getProperty("file.separator");
464         if (_sep != null) {
465             try {
466                 JavaClass.sep = _sep.charAt(0);
467             } catch (StringIndexOutOfBoundsException JavaDoc e) {
468             } // Never reached
469
}
470     }
471
472
473     /**
474      * @param attributes .
475      */

476     public void setAttributes( Attribute[] attributes ) {
477         this.attributes = attributes;
478     }
479
480
481     /**
482      * @param class_name .
483      */

484     public void setClassName( String JavaDoc class_name ) {
485         this.class_name = class_name;
486     }
487
488
489     /**
490      * @param class_name_index .
491      */

492     public void setClassNameIndex( int class_name_index ) {
493         this.class_name_index = class_name_index;
494     }
495
496
497     /**
498      * @param constant_pool .
499      */

500     public void setConstantPool( ConstantPool constant_pool ) {
501         this.constant_pool = constant_pool;
502     }
503
504
505     /**
506      * @param fields .
507      */

508     public void setFields( Field[] fields ) {
509         this.fields = fields;
510     }
511
512
513     /**
514      * Set File name of class, aka SourceFile attribute value
515      */

516     public void setFileName( String JavaDoc file_name ) {
517         this.file_name = file_name;
518     }
519
520
521     /**
522      * @param interface_names .
523      */

524     public void setInterfaceNames( String JavaDoc[] interface_names ) {
525         this.interface_names = interface_names;
526     }
527
528
529     /**
530      * @param interfaces .
531      */

532     public void setInterfaces( int[] interfaces ) {
533         this.interfaces = interfaces;
534     }
535
536
537     /**
538      * @param major .
539      */

540     public void setMajor( int major ) {
541         this.major = major;
542     }
543
544
545     /**
546      * @param methods .
547      */

548     public void setMethods( Method[] methods ) {
549         this.methods = methods;
550     }
551
552
553     /**
554      * @param minor .
555      */

556     public void setMinor( int minor ) {
557         this.minor = minor;
558     }
559
560
561     /**
562      * Set absolute path to file this class was read from.
563      */

564     public void setSourceFileName( String JavaDoc source_file_name ) {
565         this.source_file_name = source_file_name;
566     }
567
568
569     /**
570      * @param superclass_name .
571      */

572     public void setSuperclassName( String JavaDoc superclass_name ) {
573         this.superclass_name = superclass_name;
574     }
575
576
577     /**
578      * @param superclass_name_index .
579      */

580     public void setSuperclassNameIndex( int superclass_name_index ) {
581         this.superclass_name_index = superclass_name_index;
582     }
583
584
585     /**
586      * @return String representing class contents.
587      */

588     public String JavaDoc toString() {
589         String JavaDoc access = Utility.accessToString(access_flags, true);
590         access = access.equals("") ? "" : (access + " ");
591         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(128);
592         buf.append(access).append(Utility.classOrInterface(access_flags)).append(" ").append(
593                 class_name).append(" extends ").append(
594                 Utility.compactClassName(superclass_name, false)).append('\n');
595         int size = interfaces.length;
596         if (size > 0) {
597             buf.append("implements\t\t");
598             for (int i = 0; i < size; i++) {
599                 buf.append(interface_names[i]);
600                 if (i < size - 1) {
601                     buf.append(", ");
602                 }
603             }
604             buf.append('\n');
605         }
606         buf.append("filename\t\t").append(file_name).append('\n');
607         buf.append("compiled from\t\t").append(source_file_name).append('\n');
608         buf.append("compiler version\t").append(major).append(".").append(minor).append('\n');
609         buf.append("access flags\t\t").append(access_flags).append('\n');
610         buf.append("constant pool\t\t").append(constant_pool.getLength()).append(" entries\n");
611         buf.append("ACC_SUPER flag\t\t").append(isSuper()).append("\n");
612         if (attributes.length > 0) {
613             buf.append("\nAttribute(s):\n");
614             for (int i = 0; i < attributes.length; i++) {
615                 buf.append(indent(attributes[i]));
616             }
617         }
618         if (fields.length > 0) {
619             buf.append("\n").append(fields.length).append(" fields:\n");
620             for (int i = 0; i < fields.length; i++) {
621                 buf.append("\t").append(fields[i]).append('\n');
622             }
623         }
624         if (methods.length > 0) {
625             buf.append("\n").append(methods.length).append(" methods:\n");
626             for (int i = 0; i < methods.length; i++) {
627                 buf.append("\t").append(methods[i]).append('\n');
628             }
629         }
630         return buf.toString();
631     }
632
633
634     private static final String JavaDoc indent( Object JavaDoc obj ) {
635         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(obj.toString(), "\n");
636         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
637         while (tok.hasMoreTokens()) {
638             buf.append("\t").append(tok.nextToken()).append("\n");
639         }
640         return buf.toString();
641     }
642
643
644     /**
645      * @return deep copy of this class
646      */

647     public JavaClass copy() {
648         JavaClass c = null;
649         try {
650             c = (JavaClass) clone();
651             c.constant_pool = constant_pool.copy();
652             c.interfaces = (int[]) interfaces.clone();
653             c.interface_names = (String JavaDoc[]) interface_names.clone();
654             c.fields = new Field[fields.length];
655             for (int i = 0; i < fields.length; i++) {
656                 c.fields[i] = fields[i].copy(c.constant_pool);
657             }
658             c.methods = new Method[methods.length];
659             for (int i = 0; i < methods.length; i++) {
660                 c.methods[i] = methods[i].copy(c.constant_pool);
661             }
662             c.attributes = new Attribute[attributes.length];
663             for (int i = 0; i < attributes.length; i++) {
664                 c.attributes[i] = attributes[i].copy(c.constant_pool);
665             }
666         } catch (CloneNotSupportedException JavaDoc e) {
667         }
668         return c;
669     }
670
671
672     public final boolean isSuper() {
673         return (access_flags & Constants.ACC_SUPER) != 0;
674     }
675
676
677     public final boolean isClass() {
678         return (access_flags & Constants.ACC_INTERFACE) == 0;
679     }
680
681
682     /** @return returns either HEAP (generated), FILE, or ZIP
683      */

684     public final byte getSource() {
685         return source;
686     }
687
688
689     /********************* New repository functionality *********************/
690     /**
691      * Gets the ClassRepository which holds its definition. By default
692      * this is the same as SyntheticRepository.getInstance();
693      */

694     public org.apache.bcel.util.Repository getRepository() {
695         return repository;
696     }
697
698
699     /**
700      * Sets the ClassRepository which loaded the JavaClass.
701      * Should be called immediately after parsing is done.
702      */

703     public void setRepository( org.apache.bcel.util.Repository repository ) {
704         this.repository = repository;
705     }
706
707
708     /** Equivalent to runtime "instanceof" operator.
709      *
710      * @return true if this JavaClass is derived from the super class
711      * @throws ClassNotFoundException if superclasses or superinterfaces
712      * of this object can't be found
713      */

714     public final boolean instanceOf( JavaClass super_class ) throws ClassNotFoundException JavaDoc {
715         if (this.equals(super_class)) {
716             return true;
717         }
718         JavaClass[] super_classes = getSuperClasses();
719         for (int i = 0; i < super_classes.length; i++) {
720             if (super_classes[i].equals(super_class)) {
721                 return true;
722             }
723         }
724         if (super_class.isInterface()) {
725             return implementationOf(super_class);
726         }
727         return false;
728     }
729
730
731     /**
732      * @return true, if this class is an implementation of interface inter
733      * @throws ClassNotFoundException if superclasses or superinterfaces
734      * of this class can't be found
735      */

736     public boolean implementationOf( JavaClass inter ) throws ClassNotFoundException JavaDoc {
737         if (!inter.isInterface()) {
738             throw new IllegalArgumentException JavaDoc(inter.getClassName() + " is no interface");
739         }
740         if (this.equals(inter)) {
741             return true;
742         }
743         JavaClass[] super_interfaces = getAllInterfaces();
744         for (int i = 0; i < super_interfaces.length; i++) {
745             if (super_interfaces[i].equals(inter)) {
746                 return true;
747             }
748         }
749         return false;
750     }
751
752
753     /**
754      * @return the superclass for this JavaClass object, or null if this
755      * is java.lang.Object
756      * @throws ClassNotFoundException if the superclass can't be found
757      */

758     public JavaClass getSuperClass() throws ClassNotFoundException JavaDoc {
759         if ("java.lang.Object".equals(getClassName())) {
760             return null;
761         }
762         return repository.loadClass(getSuperclassName());
763     }
764
765
766     /**
767      * @return list of super classes of this class in ascending order, i.e.,
768      * java.lang.Object is always the last element
769      * @throws ClassNotFoundException if any of the superclasses can't be found
770      */

771     public JavaClass[] getSuperClasses() throws ClassNotFoundException JavaDoc {
772         JavaClass clazz = this;
773         List JavaDoc allSuperClasses = new ArrayList JavaDoc();
774         for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) {
775             allSuperClasses.add(clazz);
776         }
777         return (JavaClass[]) allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]);
778     }
779
780
781     /**
782      * Get interfaces directly implemented by this JavaClass.
783      */

784     public JavaClass[] getInterfaces() throws ClassNotFoundException JavaDoc {
785         String JavaDoc[] _interfaces = getInterfaceNames();
786         JavaClass[] classes = new JavaClass[_interfaces.length];
787         for (int i = 0; i < _interfaces.length; i++) {
788             classes[i] = repository.loadClass(_interfaces[i]);
789         }
790         return classes;
791     }
792
793
794     /**
795      * Get all interfaces implemented by this JavaClass (transitively).
796      */

797     public JavaClass[] getAllInterfaces() throws ClassNotFoundException JavaDoc {
798         ClassQueue queue = new ClassQueue();
799         Set JavaDoc allInterfaces = new TreeSet JavaDoc();
800         queue.enqueue(this);
801         while (!queue.empty()) {
802             JavaClass clazz = queue.dequeue();
803             JavaClass souper = clazz.getSuperClass();
804             JavaClass[] _interfaces = clazz.getInterfaces();
805             if (clazz.isInterface()) {
806                 allInterfaces.add(clazz);
807             } else {
808                 if (souper != null) {
809                     queue.enqueue(souper);
810                 }
811             }
812             for (int i = 0; i < _interfaces.length; i++) {
813                 queue.enqueue(_interfaces[i]);
814             }
815         }
816         return (JavaClass[]) allInterfaces.toArray(new JavaClass[allInterfaces.size()]);
817     }
818
819
820     /**
821      * @return Comparison strategy object
822      */

823     public static BCELComparator getComparator() {
824         return _cmp;
825     }
826
827
828     /**
829      * @param comparator Comparison strategy object
830      */

831     public static void setComparator( BCELComparator comparator ) {
832         _cmp = comparator;
833     }
834
835
836     /**
837      * Return value as defined by given BCELComparator strategy.
838      * By default two JavaClass objects are said to be equal when
839      * their class names are equal.
840      *
841      * @see java.lang.Object#equals(java.lang.Object)
842      */

843     public boolean equals( Object JavaDoc obj ) {
844         return _cmp.equals(this, obj);
845     }
846
847
848     /**
849      * Return the natural ordering of two JavaClasses.
850      * This ordering is based on the class name
851      */

852     public int compareTo( Object JavaDoc obj ) {
853         return getClassName().compareTo(((JavaClass) obj).getClassName());
854     }
855
856
857     /**
858      * Return value as defined by given BCELComparator strategy.
859      * By default return the hashcode of the class name.
860      *
861      * @see java.lang.Object#hashCode()
862      */

863     public int hashCode() {
864         return _cmp.hashCode(this);
865     }
866 }
867
Popular Tags