KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > gulden > util > javasource > Class


1 /*
2  * Project: BeautyJ - Customizable Java Source Code Transformer
3  * Class: de.gulden.util.javasource.Class
4  * Version: 1.1
5  *
6  * Date: 2004-09-29
7  *
8  * Note: Contains auto-generated Javadoc comments created by BeautyJ.
9  *
10  * This is licensed under the GNU General Public License (GPL)
11  * and comes with NO WARRANTY. See file license.txt for details.
12  *
13  * Author: Jens Gulden
14  * Email: beautyj@jensgulden.de
15  */

16
17 package de.gulden.util.javasource;
18
19 import de.gulden.util.javasource.jjt.Node;
20 import de.gulden.util.xml.XMLToolbox;
21 import org.w3c.dom.*;
22 import java.io.*;
23 import java.util.*;
24
25 /**
26  * Represents a Java class or interface declaration.
27  *
28  * @author Jens Gulden
29  * @version 1.1
30  */

31 public class Class extends SourceObjectDeclaredVisible implements PackageMember {
32
33     // ------------------------------------------------------------------------
34
// --- fields ---
35
// ------------------------------------------------------------------------
36

37     /**
38      * Members (fields, constructors, methods).
39      */

40     public Vector myMember;
41
42     /**
43      * Inner classes.
44      */

45     public Vector myClassInner;
46
47     /**
48      * Imported packages and classes.
49      */

50     public Vector myImport;
51
52     /**
53      * Static initializers.
54      */

55     public Vector staticInitializers;
56
57     /**
58      * Instance initializers.
59      */

60     public Vector instanceInitializers;
61
62     /**
63      * Flag to indicate that this object represents an interface declaration.
64      */

65     protected boolean interfaceFlag;
66
67     /**
68      * The interface names.
69      */

70     protected Vector interfaceNames;
71
72     /**
73      * The superclass name.
74      */

75     protected String JavaDoc superclassName;
76
77     /**
78      * Flag to indicate whether parsing pass 2 has already started (avoid cyclic calls).
79      * Also directly accessed by SourceParser.
80      */

81     transient boolean pass2 = false;
82
83     /**
84      * Temporary storage for syntax tree node.
85      * Will be be null in any externally valid object state.
86      *
87      * @see #initFromASTPass2()
88      */

89     private transient Node rootnode;
90
91     /**
92      * The qualify cache.
93      */

94     private HashMap qualifyCache;
95
96
97     // ------------------------------------------------------------------------
98
// --- constructor ---
99
// ------------------------------------------------------------------------
100

101     /**
102      * Creates a new instance of Class.
103      */

104     public Class() {
105         super();
106         myImport=new Vector();
107         interfaceFlag=false;
108         staticInitializers = new Vector();
109         instanceInitializers = new Vector();
110         interfaceNames=new Vector();
111         myMember=new Vector();
112         myClassInner=new Vector();
113         qualifyCache = new HashMap();
114     }
115
116
117     // ------------------------------------------------------------------------
118
// --- methods ---
119
// ------------------------------------------------------------------------
120

121     /**
122      * Sets the package for the class represented by this.
123      */

124     public void setPackage(Package JavaDoc p) {
125         myPackage=p;
126         registerAtPackage(p);
127     }
128
129     /**
130      * Returns the imported packages and classes.
131      */

132     public NamedIterator getImports() {
133         return new NamedIterator(myImport);
134     }
135
136     /**
137      * Returns the name of the class that gets extended by this class.
138      * If the parsed class declaration did not contain an explicit
139      * 'extends'-clause, "java.lang.Object" is returned.
140      */

141     public String JavaDoc getSuperclassName() {
142         return superclassName!=null ? superclassName : "java.lang.Object";
143     }
144
145     /**
146      * Sets the name of the class that gets extended by this class.
147      */

148     public void setSuperclassName(String JavaDoc n) {
149         superclassName=n;
150     }
151
152     /**
153      * Returns all interface names which are implemented by this class.
154      */

155     public Enumeration getInterfaceNames() {
156         return interfaceNames.elements();
157     }
158
159     /**
160      * Sets all interface names which are implemented by this class.
161      */

162     public void setInterfaceNames(String JavaDoc[] names) {
163         stringsIntoVector(names,interfaceNames);
164     }
165
166     /**
167      * Returns the code of a static class initializers.
168      */

169     public Code[] getStaticInitializers() {
170         Code[] c = new Code[staticInitializers.size()];
171         staticInitializers.copyInto(c);
172            return c;
173     }
174
175     /**
176      * Returns the code of a instance class initializers.
177      */

178     public Code[] getInstanceInitializers() {
179         Code[] c = new Code[instanceInitializers.size()];
180         instanceInitializers.copyInto(c);
181            return c;
182     }
183
184     /**
185      * Adds a static initializer.
186      */

187     public void addStaticInitializer(Code c) {
188         staticInitializers.addElement(c);
189     }
190
191     /**
192      * Adds a instance initializer.
193      */

194     public void addInstanceInitializer(Code c) {
195         instanceInitializers.addElement(c);
196     }
197
198     /**
199      * Returns all member elements of this class that match the specified type.
200      */

201     public NamedIterator getMembers(Class JavaDoc type, int modifiers) {
202         return new NamedIterator(myMember,type,modifiers);
203     }
204
205     /**
206      * Returns all member elements of this class.
207      * These are fields, constructors, methods and inner classes.
208      */

209     public NamedIterator getAllMembers() {
210         return new NamedIterator(myMember);
211     }
212
213     /**
214      * Returns all iner classes.
215      */

216     public NamedIterator getInnerClasses() {
217         return new NamedIterator(myClassInner);
218     }
219
220     /**
221      * Tests whether this Class object represents a Java interface (true),
222      * or is an ordinary class (false).
223      */

224     public boolean isInterface() {
225         return interfaceFlag;
226     }
227
228     /**
229      * Sets whether this Class object represents a Java interface (true),
230      * or is an ordinary class (false).
231      */

232     public void setInterface(boolean inter) {
233         interfaceFlag=inter;
234     }
235
236     /**
237      * Fully qualifies a class identifier, taking into account the current
238      * package of this class and the import statements.
239      *
240      * @return The fully qualified class identifier.
241      */

242     public String JavaDoc qualify(String JavaDoc name) {
243                 String JavaDoc q;
244                 String JavaDoc cached = (String JavaDoc)qualifyCache.get(name);
245                 if (cached != null) {
246                     return cached;
247                 } else {
248                     if (qualifyCache.containsKey(name)) { // had been qualified before, but not found
249
q = null;
250                     } else { // uncached search
251
q=qualifyInternal(name);
252                         qualifyCache.put(name, q);
253                     }
254                     if (q!=null) {
255                         return q;
256                     } else {
257                         throw new NoClassDefFoundError JavaDoc("cannot qualify class name "+name+" in class "+getName());
258                     }
259                 }
260
261
262     }
263
264     /**
265      * Add this class to a package.
266      */

267     public void addToPackage(Package JavaDoc p) {
268         String JavaDoc packageName=getPackage().getName();
269         Package JavaDoc pp=p.findPackage(packageName); // package already in target ClassBundle?
270
if (pp!=null) {
271             setPackage(pp); // ...yes: use this one as new associated package
272
pp.registerClass(this);
273         }
274         else { // .. no: insert own package
275
p.add(myPackage); // this has already been registered with it before
276
}
277     }
278
279     /**
280      * Output this object as XML.
281      *
282      * @return The XML tag.
283      * @see #initFromXML
284      */

285     public Element buildXML(Document d) {
286         Element e=super.buildXML(d); // tag name "class" / "interface" decided by getXMLName()
287

288         // imports
289
for (NamedIterator it=getImports();it.hasMore();) {
290             Import im=(Import)it.next();
291             e.appendChild(im.buildXML(d));
292         }
293
294         if ( ! isInterface() ) {
295             // superclass
296
Element sup=d.createElement("extends");
297             sup.setAttribute("class",superclassName);
298             e.appendChild(sup);
299
300             // implemented interfaces
301
for (Enumeration en=getInterfaceNames();en.hasMoreElements();) {
302                 String JavaDoc in=(String JavaDoc)en.nextElement();
303                 Element inE=d.createElement("implements");
304                 inE.setAttribute("interface",in);
305                 e.appendChild(inE);
306             }
307         } else { // interface
308
// extended interfaces
309
for (Enumeration en=getInterfaceNames();en.hasMoreElements();) {
310                 String JavaDoc in=(String JavaDoc)en.nextElement();
311                 Element inE=d.createElement("extends");
312                 inE.setAttribute("interface",in);
313                 e.appendChild(inE);
314             }
315         }
316
317         // initializers
318
Code[] initializers = getStaticInitializers();
319         for (int i = 0; i<initializers.length; i++) {
320             Element initializer=d.createElement("initializer");
321             initializer.setAttribute("static","yes");
322             initializer.appendChild(initializers[i].buildXML(d));
323             e.appendChild(initializer);
324         }
325         initializers = getInstanceInitializers();
326         for (int i = 0; i<initializers.length; i++) {
327             Element initializer=d.createElement("initializer");
328             initializer.appendChild(initializers[i].buildXML(d));
329             e.appendChild(initializer);
330         }
331
332         // members
333
for (NamedIterator it=getAllMembers();it.hasMore();) {
334             Member m=(Member)it.next();
335             e.appendChild(m.buildXML(d));
336         }
337
338         // inner classes and interfaces
339
for (NamedIterator it=getInnerClasses();it.hasMore();) {
340             Class JavaDoc c=(Class JavaDoc)it.next();
341             e.appendChild(c.buildXML(d));
342         }
343
344         return e;
345     }
346
347     /**
348      * Initialize this object from XML.
349      *
350      * @param element The XML tag.
351      * @throws IOException if an i/o error occurs
352      */

353     public void initFromXML(Element element) throws IOException {
354         // to be extended (not overwritten) by subclasses
355
super.initFromXML(element);
356
357         interfaceFlag=element.getTagName().equals("interface");
358
359         // imports
360
myImport.removeAllElements();
361         NodeList nl=XMLToolbox.getChildren(element,"import");
362         for (int i=0;i<nl.getLength();i++) {
363             Import im=Import.createFromXML(getPackage(),(Element)nl.item(i));
364             myImport.addElement(im);
365         }
366
367         // superclass
368
Element sup=XMLToolbox.getChild(element,"extends");
369         if (sup!=null) {
370             superclassName=XMLToolbox.getAttributeRequired(sup,"class");
371         }
372         else {
373             superclassName="java.lang.Object";
374         }
375
376         // implemented interfaces
377
interfaceNames.removeAllElements();
378         nl=XMLToolbox.getChildren(element,"implements");
379         for (int i=0;i<nl.getLength();i++) {
380             Element imE=(Element)nl.item(i);
381             String JavaDoc imp=XMLToolbox.getAttributeRequired(imE,"interface");
382             interfaceNames.addElement(imp);
383         }
384
385         // initializer
386
nl = XMLToolbox.getChildren(element,"initializer");
387         for (int i=0;i<nl.getLength();i++) {
388             Element iniE=(Element)nl.item(i);
389             Code initializer=new Code();
390             initializer.initFromXML(XMLToolbox.getChildRequired(iniE,"code"));
391             boolean isStatic = XMLToolbox.isYesAttribute(iniE, "static");
392             if (isStatic) {
393                 staticInitializers.addElement(initializer);
394             } else {
395                 instanceInitializers.addElement(initializer);
396             }
397         }
398
399         // members
400
myMember.removeAllElements();
401
402         // fields
403
nl=XMLToolbox.getChildren(element,"field");
404         for (int i=0;i<nl.getLength();i++) {
405             Field fi=new Field(this);
406             fi.initFromXML((Element)nl.item(i));
407             myMember.addElement(fi);
408         }
409
410         // constructors
411
nl=XMLToolbox.getChildren(element,"constructor");
412         for (int i=0;i<nl.getLength();i++) {
413             Constructor co=new Constructor(this);
414             co.initFromXML((Element)nl.item(i));
415             myMember.addElement(co);
416         }
417
418         // methods
419
nl=XMLToolbox.getChildren(element,"method");
420         for (int i=0;i<nl.getLength();i++) {
421             Method me=new Method(this);
422             me.initFromXML((Element)nl.item(i));
423             myMember.addElement(me);
424         }
425
426         // inner classes / interfaces
427
myClassInner.removeAllElements();
428
429         // inner classes
430
nl=XMLToolbox.getChildren(element,"class");
431         for (int i=0;i<nl.getLength();i++) {
432             ClassInner ci=new ClassInner();
433             ci.setDeclaringClass(this);
434             ci.initFromXML((Element)nl.item(i));
435             myClassInner.addElement(ci);
436         }
437
438         // inner interfaces
439
nl=XMLToolbox.getChildren(element,"interface");
440         for (int i=0;i<nl.getLength();i++) {
441             ClassInner ci=new ClassInner();
442             ci.setDeclaringClass(this);
443             ci.setInterface(true);
444             ci.initFromXML((Element)nl.item(i));
445             myClassInner.addElement(ci);
446         }
447     }
448
449     public ClassInner findInnerClass(String JavaDoc name) {
450                 String JavaDoc selfName = getName();
451                 String JavaDoc selfUnqualified=getUnqualifiedName();
452                 // fully qualified?
453
if (name.startsWith(selfName+".")) {
454                     name=name.substring(selfName.length()+1);
455                 // 'half'-qualified, starting with this class's name?
456
} else if (name.startsWith(selfUnqualified+".")) {
457                     name=name.substring(selfUnqualified.length()+1);
458                 }
459                 // name might now be unqualified name of inner class,
460
// or an inner class's inner class, either starting with
461
// a name of a direct inner class of this (i.e. "fully qualified from here on")
462
// [disabled, non-Java: or even somewhere deeper in the hierarchy of inner classes's inner classes]
463
String JavaDoc find;
464                 int dot = name.indexOf('.'); // may be an inner class's inner class, so split at first "." and iterate
465
if (dot != -1) {
466                     find = name.substring(0, dot);
467                 } else {
468                     find = name;
469                 }
470                 Class JavaDoc searchClass = this;
471                 while (find != null) {
472                     NamedIterator it = searchClass.getInnerClasses();
473                     searchClass = null;
474                     while ((searchClass==null) && it.hasMore()) {
475                         ClassInner ci=(ClassInner)it.next();
476                         if (ci.getUnqualifiedName().equals(find)) {
477                             searchClass = ci;
478                         } /* else {
479                             ClassInner ci2 = ci.findInnerClass(name); // recursion (note that this allows qualification even of completely non-qualified inner-inner(-inner...) classes, which is not recognized by the Java compiler)
480                             if (ci2 != null) {
481                                 return ci2;
482                             }
483                         } */

484                     }
485                     if (searchClass != null) {
486                         if (dot!=-1) { // at least on more
487
int nextDot = name.indexOf(',', dot+1);
488                             if (nextDot!=-1) {
489                                 find = name.substring(dot+1, nextDot);
490                             } else {
491                                 find = name.substring(dot+1);
492                             }
493                             dot = nextDot;
494                         } else {
495                             find = null;
496                         }
497                     } else {
498                         return null;
499                     }
500                 }
501                 // ...not found
502
return (ClassInner)searchClass; // might be null
503
}
504
505     protected void registerAtPackage(Package JavaDoc p) {
506         // will be overwritten by ClassInner
507
p.registerClass(this);
508     }
509
510     /**
511      * Fully qualifies a class identifier, taking into account the current
512      * package of this class and the import statements.
513      *
514      * @return The fully qualified class identifier.
515      */

516     protected String JavaDoc qualifyInternal(String JavaDoc name) {
517         String JavaDoc q;
518         NamedIterator it;
519
520
521         this.initFromASTPass2(); // make sure this has run before (if called from another class's qualifyInternal), will immediately return if called before
522

523
524         if (isPrimitive(name)) {
525             return name;
526         }
527
528         String JavaDoc selfUnqualified=getUnqualifiedName();
529
530         // self?
531
if (name.equals(selfUnqualified)) {
532             return getName();
533         }
534
535         Package JavaDoc basePackage=getPackage().getBasePackage();
536
537         // is already fully qualified?
538
// ...from sources
539
if (basePackage.findClass(name)!=null) {
540             return name;
541         }
542         // ...from classpath
543
try {
544             java.lang.Class.forName(name);
545             return name;
546         }
547         catch (ClassNotFoundException JavaDoc cnfe) {
548             // fall through
549
}
550
551         // qualifiable by single-class-import?
552
it=getImports();
553         while (it.hasMore()) {
554             Import im=(Import)it.next();
555             if (im instanceof ImportClass) {
556                 q=im.qualify(name);
557                 if (q!=null) {
558                     return q;
559                 }
560             }
561         }
562
563         // try to qualify to be in same package (if not already)
564
String JavaDoc packageName=getPackage().getName();
565         if ((!packageName.equals("")) && (!name.startsWith(packageName+"."))) {
566             q=packageName+"."+name;
567         }
568         else {
569             q=name;
570         }
571         Class JavaDoc c=basePackage.findClass(q); // existing?
572
if (c!=null) {
573             return q;
574         }
575
576         // inner class of this class?
577
ClassInner ci = findInnerClass(name);
578         if (ci != null) {
579             return ci.getName();
580         }
581
582         int lastdot = name.lastIndexOf('.');
583
584         // might be a superclass's inner class
585
// (this does not take care whether a superclass's inner class is private, so should be called quite late in this method to avoid ambiguities)
586
/*
587         String sup = this.getSuperclassName();
588         if (lastdot != -1) {
589             String f = name.substring(0, pos);
590             String r = name.substring(pos+1);
591             String first = qualifyInternal(f); // might be a superclass or superclass's inner class, recursion
592             if (first != null) {
593                 if (first.startsWith(sup)) { // yes, superclass or superclass's inner class
594                     String supInner = qualifyInternal(first + "." + r); // recursion, test if full qualificaton is correct
595                     if (supInner != null) {
596                         return supInner;
597                     }
598                 }
599             }
600         } else { // unqualified, still could be a superclass's inner class
601             if (!sup.equals("java.lang.Object")) {
602                 String supInner = qualifyInternal(sup + "." +name);
603                 if (supInner != null) {
604                     return supInner;
605                 }
606             }
607         }
608         */

609
610         // inner class from other class (from sources or classpath)?
611
if (lastdot != -1) {
612             String JavaDoc outerName = name.substring(0, lastdot);
613             // try to qualify possible outer class (can only happen from classpath, would have already been found by Package.findClass() if from sources)
614
String JavaDoc outerQ;
615             if (Package.isSourcePackage(basePackage, outerName)) { // optimization
616
outerQ = null;
617             } else {
618                 try {
619                     outerQ = qualify(outerName); // recursion (use qualify() to allow caching)
620
} catch (NoClassDefFoundError JavaDoc ncdfe) {
621                     outerQ = null;
622                 }
623             }
624             if (outerQ != null) {
625                 // known from sources?
626
q = outerQ + "." + name.substring(lastdot+1);
627                 Class JavaDoc qcl = basePackage.findClass(q);
628                 if (qcl!= null) {
629                     return q;
630                 }
631                 // exists in classpath?
632
String JavaDoc q2 = outerQ + "$" + name.substring(lastdot+1);
633                 try {
634                     //java.lang.Class.forName(name); (no idea why this sometimes does not work, so use:)
635
ClassLoader JavaDoc cl = ClassLoader.getSystemClassLoader(); //oc.getClassLoader();
636
java.lang.Class JavaDoc dummy = cl.loadClass(q2);
637                     return q;
638                 }
639                 catch (ClassNotFoundException JavaDoc cnfe) {
640                     // fallthrough
641
}
642                 // now known in sources, after outer has been loaded?
643
//return qualifyInternal(name); // recursion
644
}
645         }
646
647         // might be an unqualified superclass's inner class
648
if (lastdot == -1) {
649             String JavaDoc sup = this.getSuperclassName();
650             while ((sup!=null) && (!sup.equals("java.lang.Object"))) {
651                 Class JavaDoc superclass = basePackage.findClass(sup);
652                 if (!name.startsWith(sup+".")) {
653                         try {
654                             String JavaDoc supInner;
655                             Class JavaDoc qc;
656                             if (superclass != null) {
657                                 qc = superclass;
658                             } else {
659                                 qc = this;
660                             }
661                             String JavaDoc supInnerName = sup + "." + name;
662                             supInner = qc.qualify(supInnerName); // recursion (use qualify() to allow caching)
663
return supInner;
664                         } catch (NoClassDefFoundError JavaDoc ncdfe) {
665                             // fallthrough
666
}
667                 }
668                 // get superclass of superclass...
669
if (superclass != null) { // could be found in sources
670
//if (superclass.superclassName == null) { // (do not access getSuperclassName(), use this to find out whether initFromAST2 has been called before (hacking) (must be done to avoid cycles in rare cases))
671
superclass.initFromASTPass2(); // make sure that this is performed before we ask for superclass
672
sup = superclass.getSuperclassName();
673                 } else {
674                     try {
675                         java.lang.Class JavaDoc cl = java.lang.Class.forName(sup);
676                         cl = cl.getSuperclass();
677                         if (cl != null) {
678                             sup = cl.getName();
679                         } else {
680                             sup = null;
681                         }
682                     } catch (ClassNotFoundException JavaDoc cnfe) {
683                         sup = null;
684                     }
685                 }
686             }
687         }
688
689         // can another source file for that class be loaded from the same package (which had not been loaded before, otherwise would have been found by now)?
690
if ( (this.rootnode != null) && (! (this instanceof ClassInner))) { // do not do this in pass 2 (calling this method in pass 2 when testing for need of auto-import of unqualified classes that had been qualified in the original source)
691
String JavaDoc sourcename;
692             if ((!packageName.equals("")) && (name.startsWith(packageName+"."))) {
693                 sourcename = name.substring(packageName.length()+1);
694             }else {
695                 sourcename = name;
696             }
697             if (sourcename.indexOf('.')==-1) {
698                 sourcename += ".java";
699                 File thisSource = new File(this.rootnode.getSource());
700                 File source = new File(thisSource.getParentFile(), sourcename);
701                 if (source.exists()) {
702                     try {
703                         SourceParser.parse(source, basePackage, null);
704                         // and do everything again, now with this extra source file parsed
705
return qualifyInternal(name); // recursion
706
} catch (java.lang.Exception JavaDoc e) {
707                         //nop, ignore errors and treat like unavailable source
708
}
709                 }
710             }
711         }
712
713         // if this is an inner class, try to further qualify by outer class (e.g. to find inner classes of superclasses of the outer class)
714
if (this instanceof ClassInner) {
715             try {
716                 String JavaDoc s = getDeclaringClass().qualify(name); // recursion (use qualify() instead of qualifyInternal() to allow caching)
717
return s;
718             } catch (NoClassDefFoundError JavaDoc ncdfe) {
719                 // fallthrough NO
720
return null; // can already return, because outer class would find package-imports (they are naturally the same for inner classes)
721
}
722         }
723
724         // qualifiable by package-import?
725
it=getImports();
726         while (it.hasMore()) {
727             Import im=(Import)it.next();
728             if (im instanceof ImportPackage) {
729                 q=im.qualify(name);
730                 if (q!=null) {
731                     return q;
732                 }
733             }
734         }
735
736         // ...from java.lang.*? (can be done already here, because if e.g. an inner class has the same name as a class in java.lang, the compiler would require an implicit class import, and so we would have found the class already before reaching here)
737
q="java.lang."+name;
738         try {
739             java.lang.Class.forName(q);
740             return q;
741         }
742         catch (ClassNotFoundException JavaDoc cnfe) {
743             // fall through
744
}
745
746         // if reached here, not found
747
return null;
748     }
749
750     /**
751      * Tests whether a type name denotes a primitive type.
752      */

753     protected boolean isPrimitive(String JavaDoc type) {
754         return type.equals("boolean")
755         || type.equals("byte")
756         || type.equals("char")
757         || type.equals("short")
758         || type.equals("int")
759         || type.equals("long")
760         || type.equals("float")
761         || type.equals("double")
762         || type.equals("void");
763     }
764
765     /**
766      * Returns the name of the XML tag representing this SourceObject.
767      */

768     protected String JavaDoc getXMLName() {
769         // overwrites SourceObject.getXMLName()
770
return interfaceFlag?"interface":"class";
771     }
772
773     /**
774      * Initialize this object from parsed Java code.
775      *
776      * @param rootnode The corresponding node in the abstract syntax tree (AST).
777      */

778     void initFromAST(Node rootnode) {
779         Node n;
780         Node[] nodes;
781
782         // get name
783
super.initFromAST(rootnode); // sets 'name' to unqualified name
784
String JavaDoc packageName=getPackage().getName();
785         if (packageName.length()>0) {
786             name=packageName+"."+name; // qualify name if class is not member of base package
787
}
788
789         // get inner classes / interfaces...
790
myClassInner.removeAllElements();
791         // ...inner classes
792
nodes=rootnode.getChildren(JJT_INNERCLASS);
793         for (int i=0;i<nodes.length;i++) {
794             ClassInner c=new ClassInner();
795             c.setDeclaringClass(this);
796             c.initFromAST(nodes[i]);
797             myClassInner.addElement(c);
798         }
799         // ...inner interfaces
800
nodes=rootnode.getChildren(JJT_INNERINTERFACE);
801         for (int i=0;i<nodes.length;i++) {
802             ClassInner c=new ClassInner();
803             c.setDeclaringClass(this);
804             c.setInterface(true);
805             c.initFromAST(nodes[i]);
806             myClassInner.addElement(c);
807         }
808
809         this.rootnode=rootnode; // remember for pass 2
810
}
811
812     /**
813      * Pass 2.
814      */

815     void initFromASTPass2() {
816         Node n;
817         Node[] nodes;
818
819         if ((!pass2) && (rootnode != null)) { // (rootnode also null if XML input)
820

821             pass2 = true;
822
823             Class JavaDoc q; // class declarating identifiers need to be resolved via the outer class
824
if (this instanceof ClassInner) {
825                 q = this.getDeclaringClass();
826             } else {
827                 q = this;
828             }
829
830             // get superclass
831
n=rootnode.getChild(JJT_SUPERCLASS);
832             if (n!=null) {
833                 superclassName= q.qualify( n.getName() );
834             }
835             else {
836                 superclassName="java.lang.Object";
837             }
838
839             // get implemented interfaces
840
interfaceNames.removeAllElements();
841             nodes=rootnode.getChildren(JJT_IMPLEMENTS);
842             for (int i=0;i<nodes.length;i++) {
843                 String JavaDoc name=nodes[i].getName();
844                 interfaceNames.addElement( q.qualify(name) );
845             }
846
847             staticInitializers.removeAllElements();
848             instanceInitializers.removeAllElements();
849             nodes=rootnode.getChildren(JJT_INITIALIZER);
850             for (int i=0;i<nodes.length;i++) {
851                 Code ini = new Code();
852                 ini.initFromAST(nodes[i].getChild(JJT_CODE));
853                 boolean isStatic = nodes[i].hasChild(JJT_STATIC);
854                 if (isStatic) {
855                     addStaticInitializer(ini);
856                 } else {
857                     addInstanceInitializer(ini);
858                 }
859             }
860
861             // get members...
862

863             // inner classes and interfaces... (must do first so that inner classes are known when fields and methods are analyzed)
864
NamedIterator it;
865             it=getInnerClasses();
866             while (it.hasMore()) {
867                 ClassInner c=(ClassInner)it.next();
868                 c.initFromASTPass2();
869             }
870
871             // ...fields
872
myMember.removeAllElements();
873             nodes=rootnode.getChildren(JJT_FIELD);
874             for (int i=0;i<nodes.length;i++) {
875                 Node[] vars=nodes[i].getChildren(JJT_FIELDVAR);
876                 for (int j=0;j<vars.length;j++) {
877                     Field f=new Field(this);
878                     f.initFromAST(nodes[i],vars[j]);
879                     myMember.addElement(f);
880                 }
881             }
882
883             // ...constructors
884
nodes=rootnode.getChildren(JJT_CONSTRUCTOR);
885             for (int i=0;i<nodes.length;i++) {
886                 Constructor c=new Constructor(this);
887                 c.initFromAST(nodes[i]);
888                 myMember.addElement(c);
889             }
890
891             // ...methods
892
nodes=rootnode.getChildren(JJT_METHOD);
893             for (int i=0;i<nodes.length;i++) {
894                 Method c=new Method(this);
895                 c.initFromAST(nodes[i]);
896                 myMember.addElement(c);
897             }
898
899             rootnode=null; // free memory and remove temporal reference to non-serializable object
900
}
901     }
902
903 } // end Class
904
Popular Tags