001: /*
002: * Project: BeautyJ - Customizable Java Source Code Transformer
003: * Class: de.gulden.util.javasource.Class
004: * Version: 1.1
005: *
006: * Date: 2004-09-29
007: *
008: * Note: Contains auto-generated Javadoc comments created by BeautyJ.
009: *
010: * This is licensed under the GNU General Public License (GPL)
011: * and comes with NO WARRANTY. See file license.txt for details.
012: *
013: * Author: Jens Gulden
014: * Email: beautyj@jensgulden.de
015: */
016:
017: package de.gulden.util.javasource;
018:
019: import de.gulden.util.javasource.jjt.Node;
020: import de.gulden.util.xml.XMLToolbox;
021: import org.w3c.dom.*;
022: import java.io.*;
023: import java.util.*;
024:
025: /**
026: * Represents a Java class or interface declaration.
027: *
028: * @author Jens Gulden
029: * @version 1.1
030: */
031: public class Class extends SourceObjectDeclaredVisible implements
032: PackageMember {
033:
034: // ------------------------------------------------------------------------
035: // --- fields ---
036: // ------------------------------------------------------------------------
037:
038: /**
039: * Members (fields, constructors, methods).
040: */
041: public Vector myMember;
042:
043: /**
044: * Inner classes.
045: */
046: public Vector myClassInner;
047:
048: /**
049: * Imported packages and classes.
050: */
051: public Vector myImport;
052:
053: /**
054: * Static initializers.
055: */
056: public Vector staticInitializers;
057:
058: /**
059: * Instance initializers.
060: */
061: public Vector instanceInitializers;
062:
063: /**
064: * Flag to indicate that this object represents an interface declaration.
065: */
066: protected boolean interfaceFlag;
067:
068: /**
069: * The interface names.
070: */
071: protected Vector interfaceNames;
072:
073: /**
074: * The superclass name.
075: */
076: protected String super className;
077:
078: /**
079: * Flag to indicate whether parsing pass 2 has already started (avoid cyclic calls).
080: * Also directly accessed by SourceParser.
081: */
082: transient boolean pass2 = false;
083:
084: /**
085: * Temporary storage for syntax tree node.
086: * Will be be null in any externally valid object state.
087: *
088: * @see #initFromASTPass2()
089: */
090: private transient Node rootnode;
091:
092: /**
093: * The qualify cache.
094: */
095: private HashMap qualifyCache;
096:
097: // ------------------------------------------------------------------------
098: // --- constructor ---
099: // ------------------------------------------------------------------------
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: // --- methods ---
118: // ------------------------------------------------------------------------
119:
120: /**
121: * Sets the package for the class represented by this.
122: */
123: public void setPackage(Package p) {
124: myPackage = p;
125: registerAtPackage(p);
126: }
127:
128: /**
129: * Returns the imported packages and classes.
130: */
131: public NamedIterator getImports() {
132: return new NamedIterator(myImport);
133: }
134:
135: /**
136: * Returns the name of the class that gets extended by this class.
137: * If the parsed class declaration did not contain an explicit
138: * 'extends'-clause, "java.lang.Object" is returned.
139: */
140: public String getSuperclassName() {
141: return super className != null ? super className
142: : "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 n) {
149: super className = 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[] 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 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 qualify(String name) {
243: String q;
244: String cached = (String) 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(
258: "cannot qualify class name " + name
259: + " in class " + getName());
260: }
261: }
262:
263: }
264:
265: /**
266: * Add this class to a package.
267: */
268: public void addToPackage(Package p) {
269: String packageName = getPackage().getName();
270: Package pp = p.findPackage(packageName); // package already in target ClassBundle?
271: if (pp != null) {
272: setPackage(pp); // ...yes: use this one as new associated package
273: pp.registerClass(this );
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", super className);
298: e.appendChild(sup);
299:
300: // implemented interfaces
301: for (Enumeration en = getInterfaceNames(); en
302: .hasMoreElements();) {
303: String in = (String) en.nextElement();
304: Element inE = d.createElement("implements");
305: inE.setAttribute("interface", in);
306: e.appendChild(inE);
307: }
308: } else { // interface
309: // extended interfaces
310: for (Enumeration en = getInterfaceNames(); en
311: .hasMoreElements();) {
312: String in = (String) en.nextElement();
313: Element inE = d.createElement("extends");
314: inE.setAttribute("interface", in);
315: e.appendChild(inE);
316: }
317: }
318:
319: // initializers
320: Code[] initializers = getStaticInitializers();
321: for (int i = 0; i < initializers.length; i++) {
322: Element initializer = d.createElement("initializer");
323: initializer.setAttribute("static", "yes");
324: initializer.appendChild(initializers[i].buildXML(d));
325: e.appendChild(initializer);
326: }
327: initializers = getInstanceInitializers();
328: for (int i = 0; i < initializers.length; i++) {
329: Element initializer = d.createElement("initializer");
330: initializer.appendChild(initializers[i].buildXML(d));
331: e.appendChild(initializer);
332: }
333:
334: // members
335: for (NamedIterator it = getAllMembers(); it.hasMore();) {
336: Member m = (Member) it.next();
337: e.appendChild(m.buildXML(d));
338: }
339:
340: // inner classes and interfaces
341: for (NamedIterator it = getInnerClasses(); it.hasMore();) {
342: Class c = (Class) it.next();
343: e.appendChild(c.buildXML(d));
344: }
345:
346: return e;
347: }
348:
349: /**
350: * Initialize this object from XML.
351: *
352: * @param element The XML tag.
353: * @throws IOException if an i/o error occurs
354: */
355: public void initFromXML(Element element) throws IOException {
356: // to be extended (not overwritten) by subclasses
357: super .initFromXML(element);
358:
359: interfaceFlag = element.getTagName().equals("interface");
360:
361: // imports
362: myImport.removeAllElements();
363: NodeList nl = XMLToolbox.getChildren(element, "import");
364: for (int i = 0; i < nl.getLength(); i++) {
365: Import im = Import.createFromXML(getPackage(), (Element) nl
366: .item(i));
367: myImport.addElement(im);
368: }
369:
370: // superclass
371: Element sup = XMLToolbox.getChild(element, "extends");
372: if (sup != null) {
373: super className = XMLToolbox.getAttributeRequired(sup,
374: "class");
375: } else {
376: super className = "java.lang.Object";
377: }
378:
379: // implemented interfaces
380: interfaceNames.removeAllElements();
381: nl = XMLToolbox.getChildren(element, "implements");
382: for (int i = 0; i < nl.getLength(); i++) {
383: Element imE = (Element) nl.item(i);
384: String imp = XMLToolbox.getAttributeRequired(imE,
385: "interface");
386: interfaceNames.addElement(imp);
387: }
388:
389: // initializer
390: nl = XMLToolbox.getChildren(element, "initializer");
391: for (int i = 0; i < nl.getLength(); i++) {
392: Element iniE = (Element) nl.item(i);
393: Code initializer = new Code();
394: initializer.initFromXML(XMLToolbox.getChildRequired(iniE,
395: "code"));
396: boolean isStatic = XMLToolbox
397: .isYesAttribute(iniE, "static");
398: if (isStatic) {
399: staticInitializers.addElement(initializer);
400: } else {
401: instanceInitializers.addElement(initializer);
402: }
403: }
404:
405: // members
406: myMember.removeAllElements();
407:
408: // fields
409: nl = XMLToolbox.getChildren(element, "field");
410: for (int i = 0; i < nl.getLength(); i++) {
411: Field fi = new Field(this );
412: fi.initFromXML((Element) nl.item(i));
413: myMember.addElement(fi);
414: }
415:
416: // constructors
417: nl = XMLToolbox.getChildren(element, "constructor");
418: for (int i = 0; i < nl.getLength(); i++) {
419: Constructor co = new Constructor(this );
420: co.initFromXML((Element) nl.item(i));
421: myMember.addElement(co);
422: }
423:
424: // methods
425: nl = XMLToolbox.getChildren(element, "method");
426: for (int i = 0; i < nl.getLength(); i++) {
427: Method me = new Method(this );
428: me.initFromXML((Element) nl.item(i));
429: myMember.addElement(me);
430: }
431:
432: // inner classes / interfaces
433: myClassInner.removeAllElements();
434:
435: // inner classes
436: nl = XMLToolbox.getChildren(element, "class");
437: for (int i = 0; i < nl.getLength(); i++) {
438: ClassInner ci = new ClassInner();
439: ci.setDeclaringClass(this );
440: ci.initFromXML((Element) nl.item(i));
441: myClassInner.addElement(ci);
442: }
443:
444: // inner interfaces
445: nl = XMLToolbox.getChildren(element, "interface");
446: for (int i = 0; i < nl.getLength(); i++) {
447: ClassInner ci = new ClassInner();
448: ci.setDeclaringClass(this );
449: ci.setInterface(true);
450: ci.initFromXML((Element) nl.item(i));
451: myClassInner.addElement(ci);
452: }
453: }
454:
455: public ClassInner findInnerClass(String name) {
456: String selfName = getName();
457: String selfUnqualified = getUnqualifiedName();
458: // fully qualified?
459: if (name.startsWith(selfName + ".")) {
460: name = name.substring(selfName.length() + 1);
461: // 'half'-qualified, starting with this class's name?
462: } else if (name.startsWith(selfUnqualified + ".")) {
463: name = name.substring(selfUnqualified.length() + 1);
464: }
465: // name might now be unqualified name of inner class,
466: // or an inner class's inner class, either starting with
467: // a name of a direct inner class of this (i.e. "fully qualified from here on")
468: // [disabled, non-Java: or even somewhere deeper in the hierarchy of inner classes's inner classes]
469: String find;
470: int dot = name.indexOf('.'); // may be an inner class's inner class, so split at first "." and iterate
471: if (dot != -1) {
472: find = name.substring(0, dot);
473: } else {
474: find = name;
475: }
476: Class searchClass = this ;
477: while (find != null) {
478: NamedIterator it = searchClass.getInnerClasses();
479: searchClass = null;
480: while ((searchClass == null) && it.hasMore()) {
481: ClassInner ci = (ClassInner) it.next();
482: if (ci.getUnqualifiedName().equals(find)) {
483: searchClass = ci;
484: } /* else {
485: 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)
486: if (ci2 != null) {
487: return ci2;
488: }
489: } */
490: }
491: if (searchClass != null) {
492: if (dot != -1) { // at least on more
493: int nextDot = name.indexOf(',', dot + 1);
494: if (nextDot != -1) {
495: find = name.substring(dot + 1, nextDot);
496: } else {
497: find = name.substring(dot + 1);
498: }
499: dot = nextDot;
500: } else {
501: find = null;
502: }
503: } else {
504: return null;
505: }
506: }
507: // ...not found
508: return (ClassInner) searchClass; // might be null
509: }
510:
511: protected void registerAtPackage(Package p) {
512: // will be overwritten by ClassInner
513: p.registerClass(this );
514: }
515:
516: /**
517: * Fully qualifies a class identifier, taking into account the current
518: * package of this class and the import statements.
519: *
520: * @return The fully qualified class identifier.
521: */
522: protected String qualifyInternal(String name) {
523: String q;
524: NamedIterator it;
525:
526: this .initFromASTPass2(); // make sure this has run before (if called from another class's qualifyInternal), will immediately return if called before
527:
528: if (isPrimitive(name)) {
529: return name;
530: }
531:
532: String selfUnqualified = getUnqualifiedName();
533:
534: // self?
535: if (name.equals(selfUnqualified)) {
536: return getName();
537: }
538:
539: Package basePackage = getPackage().getBasePackage();
540:
541: // is already fully qualified?
542: // ...from sources
543: if (basePackage.findClass(name) != null) {
544: return name;
545: }
546: // ...from classpath
547: try {
548: java.lang.Class.forName(name);
549: return name;
550: } catch (ClassNotFoundException cnfe) {
551: // fall through
552: }
553:
554: // qualifiable by single-class-import?
555: it = getImports();
556: while (it.hasMore()) {
557: Import im = (Import) it.next();
558: if (im instanceof ImportClass) {
559: q = im.qualify(name);
560: if (q != null) {
561: return q;
562: }
563: }
564: }
565:
566: // try to qualify to be in same package (if not already)
567: String packageName = getPackage().getName();
568: if ((!packageName.equals(""))
569: && (!name.startsWith(packageName + "."))) {
570: q = packageName + "." + name;
571: } else {
572: q = name;
573: }
574: Class c = basePackage.findClass(q); // existing?
575: if (c != null) {
576: return q;
577: }
578:
579: // inner class of this class?
580: ClassInner ci = findInnerClass(name);
581: if (ci != null) {
582: return ci.getName();
583: }
584:
585: int lastdot = name.lastIndexOf('.');
586:
587: // might be a superclass's inner class
588: // (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)
589: /*
590: String sup = this.getSuperclassName();
591: if (lastdot != -1) {
592: String f = name.substring(0, pos);
593: String r = name.substring(pos+1);
594: String first = qualifyInternal(f); // might be a superclass or superclass's inner class, recursion
595: if (first != null) {
596: if (first.startsWith(sup)) { // yes, superclass or superclass's inner class
597: String supInner = qualifyInternal(first + "." + r); // recursion, test if full qualificaton is correct
598: if (supInner != null) {
599: return supInner;
600: }
601: }
602: }
603: } else { // unqualified, still could be a superclass's inner class
604: if (!sup.equals("java.lang.Object")) {
605: String supInner = qualifyInternal(sup + "." +name);
606: if (supInner != null) {
607: return supInner;
608: }
609: }
610: }
611: */
612:
613: // inner class from other class (from sources or classpath)?
614: if (lastdot != -1) {
615: String outerName = name.substring(0, lastdot);
616: // try to qualify possible outer class (can only happen from classpath, would have already been found by Package.findClass() if from sources)
617: String outerQ;
618: if (Package.isSourcePackage(basePackage, outerName)) { // optimization
619: outerQ = null;
620: } else {
621: try {
622: outerQ = qualify(outerName); // recursion (use qualify() to allow caching)
623: } catch (NoClassDefFoundError ncdfe) {
624: outerQ = null;
625: }
626: }
627: if (outerQ != null) {
628: // known from sources?
629: q = outerQ + "." + name.substring(lastdot + 1);
630: Class qcl = basePackage.findClass(q);
631: if (qcl != null) {
632: return q;
633: }
634: // exists in classpath?
635: String q2 = outerQ + "$" + name.substring(lastdot + 1);
636: try {
637: //java.lang.Class.forName(name); (no idea why this sometimes does not work, so use:)
638: ClassLoader cl = ClassLoader.getSystemClassLoader(); //oc.getClassLoader();
639: java.lang.Class dummy = cl.loadClass(q2);
640: return q;
641: } catch (ClassNotFoundException cnfe) {
642: // fallthrough
643: }
644: // now known in sources, after outer has been loaded?
645: //return qualifyInternal(name); // recursion
646: }
647: }
648:
649: // might be an unqualified superclass's inner class
650: if (lastdot == -1) {
651: String sup = this .getSuperclassName();
652: while ((sup != null) && (!sup.equals("java.lang.Object"))) {
653: Class super class = basePackage.findClass(sup);
654: if (!name.startsWith(sup + ".")) {
655: try {
656: String supInner;
657: Class qc;
658: if (super class != null) {
659: qc = super class;
660: } else {
661: qc = this ;
662: }
663: String supInnerName = sup + "." + name;
664: supInner = qc.qualify(supInnerName); // recursion (use qualify() to allow caching)
665: return supInner;
666: } catch (NoClassDefFoundError ncdfe) {
667: // fallthrough
668: }
669: }
670: // get superclass of superclass...
671: if (super class != null) { // could be found in sources
672: //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))
673: super class.initFromASTPass2(); // make sure that this is performed before we ask for superclass
674: sup = super class.getSuperclassName();
675: } else {
676: try {
677: java.lang.Class cl = java.lang.Class
678: .forName(sup);
679: cl = cl.getSuperclass();
680: if (cl != null) {
681: sup = cl.getName();
682: } else {
683: sup = null;
684: }
685: } catch (ClassNotFoundException cnfe) {
686: sup = null;
687: }
688: }
689: }
690: }
691:
692: // 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)?
693: 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)
694: String sourcename;
695: if ((!packageName.equals(""))
696: && (name.startsWith(packageName + "."))) {
697: sourcename = name.substring(packageName.length() + 1);
698: } else {
699: sourcename = name;
700: }
701: if (sourcename.indexOf('.') == -1) {
702: sourcename += ".java";
703: File this Source = new File(this .rootnode.getSource());
704: File source = new File(this Source.getParentFile(),
705: sourcename);
706: if (source.exists()) {
707: try {
708: SourceParser.parse(source, basePackage, null);
709: // and do everything again, now with this extra source file parsed
710: return qualifyInternal(name); // recursion
711: } catch (java.lang.Exception e) {
712: //nop, ignore errors and treat like unavailable source
713: }
714: }
715: }
716: }
717:
718: // 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)
719: if (this instanceof ClassInner) {
720: try {
721: String s = getDeclaringClass().qualify(name); // recursion (use qualify() instead of qualifyInternal() to allow caching)
722: return s;
723: } catch (NoClassDefFoundError ncdfe) {
724: // fallthrough NO
725: return null; // can already return, because outer class would find package-imports (they are naturally the same for inner classes)
726: }
727: }
728:
729: // qualifiable by package-import?
730: it = getImports();
731: while (it.hasMore()) {
732: Import im = (Import) it.next();
733: if (im instanceof ImportPackage) {
734: q = im.qualify(name);
735: if (q != null) {
736: return q;
737: }
738: }
739: }
740:
741: // ...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)
742: q = "java.lang." + name;
743: try {
744: java.lang.Class.forName(q);
745: return q;
746: } catch (ClassNotFoundException cnfe) {
747: // fall through
748: }
749:
750: // if reached here, not found
751: return null;
752: }
753:
754: /**
755: * Tests whether a type name denotes a primitive type.
756: */
757: protected boolean isPrimitive(String type) {
758: return type.equals("boolean") || type.equals("byte")
759: || type.equals("char") || type.equals("short")
760: || type.equals("int") || type.equals("long")
761: || type.equals("float") || 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 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 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 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: super className = q.qualify(n.getName());
834: } else {
835: super className = "java.lang.Object";
836: }
837:
838: // get implemented interfaces
839: interfaceNames.removeAllElements();
840: nodes = rootnode.getChildren(JJT_IMPLEMENTS);
841: for (int i = 0; i < nodes.length; i++) {
842: String name = nodes[i].getName();
843: interfaceNames.addElement(q.qualify(name));
844: }
845:
846: staticInitializers.removeAllElements();
847: instanceInitializers.removeAllElements();
848: nodes = rootnode.getChildren(JJT_INITIALIZER);
849: for (int i = 0; i < nodes.length; i++) {
850: Code ini = new Code();
851: ini.initFromAST(nodes[i].getChild(JJT_CODE));
852: boolean isStatic = nodes[i].hasChild(JJT_STATIC);
853: if (isStatic) {
854: addStaticInitializer(ini);
855: } else {
856: addInstanceInitializer(ini);
857: }
858: }
859:
860: // get members...
861:
862: // inner classes and interfaces... (must do first so that inner classes are known when fields and methods are analyzed)
863: NamedIterator it;
864: it = getInnerClasses();
865: while (it.hasMore()) {
866: ClassInner c = (ClassInner) it.next();
867: c.initFromASTPass2();
868: }
869:
870: // ...fields
871: myMember.removeAllElements();
872: nodes = rootnode.getChildren(JJT_FIELD);
873: for (int i = 0; i < nodes.length; i++) {
874: Node[] vars = nodes[i].getChildren(JJT_FIELDVAR);
875: for (int j = 0; j < vars.length; j++) {
876: Field f = new Field(this );
877: f.initFromAST(nodes[i], vars[j]);
878: myMember.addElement(f);
879: }
880: }
881:
882: // ...constructors
883: nodes = rootnode.getChildren(JJT_CONSTRUCTOR);
884: for (int i = 0; i < nodes.length; i++) {
885: Constructor c = new Constructor(this );
886: c.initFromAST(nodes[i]);
887: myMember.addElement(c);
888: }
889:
890: // ...methods
891: nodes = rootnode.getChildren(JJT_METHOD);
892: for (int i = 0; i < nodes.length; i++) {
893: Method c = new Method(this );
894: c.initFromAST(nodes[i]);
895: myMember.addElement(c);
896: }
897:
898: rootnode = null; // free memory and remove temporal reference to non-serializable object
899: }
900: }
901:
902: } // end Class
|