KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > tools > doclets > standard > ClassWriter


1 /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the debugger and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  */

22 package org.aspectj.tools.doclets.standard;
23
24 import org.aspectj.ajdoc.AdviceDoc;
25 import org.aspectj.ajdoc.AspectDoc;
26 import org.aspectj.ajdoc.IntroducedDoc;
27 import org.aspectj.ajdoc.IntroducedSuperDoc;
28 import org.aspectj.ajdoc.IntroductionDoc;
29 import org.aspectj.ajdoc.OfClauseDoc;
30 import org.aspectj.ajdoc.OfEachObjectDoc;
31
32 import com.sun.javadoc.ClassDoc;
33 import com.sun.javadoc.ExecutableMemberDoc;
34 import com.sun.javadoc.MemberDoc;
35 import com.sun.tools.doclets.ClassTree;
36 import com.sun.tools.doclets.DirectoryManager;
37 import com.sun.tools.doclets.DocletAbortException;
38
39 import java.io.IOException JavaDoc;
40 import java.util.ArrayList JavaDoc;
41 import java.util.Collection JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Set JavaDoc;
45 import java.util.TreeSet JavaDoc;
46
47 public class ClassWriter extends com.sun.tools.doclets.standard.ClassWriter {
48
49     /**
50      * The MethodSubWriter that prints out the methods
51      * of <code>classdoc</code>.
52      */

53     protected MethodSubWriter ourMethodSubWriter;
54     
55     /**
56      * The ConstructorSubWriter that prints out the constructors
57      * of <code>classdoc</code>.
58      */

59     protected ConstructorSubWriter ourConstrSubWriter;
60     
61     /**
62      * The FieldSubWriter that prints out the fields
63      * of <code>classdoc</code>.
64      */

65     protected FieldSubWriter ourFieldSubWriter;
66     
67     /**
68      * The ClassSubWriter that prints out the classs
69      * of <code>classdoc</code>.
70      */

71     protected ClassSubWriter ourInnerSubWriter;
72     
73     /**
74      * The PointcutSubWriter that prints out the pointcuts
75      * of <code>classdoc</code>.
76      */

77     protected PointcutSubWriter pointcutSubWriter = null;
78     
79     /**
80      * The SuperIntroductionSubWriter that prints out the superintroductions
81      * of <code>classdoc</code>.
82      */

83     protected SuperIntroductionSubWriter superIntroductionSubWriter = null;
84     
85     /**
86      * The FieldIntroductionSubWriter that prints out the fieldintroductions
87      * of <code>classdoc</code>.
88      */

89     protected FieldIntroductionSubWriter fieldIntroductionSubWriter = null;
90     
91     /**
92      * The ConstructorIntroductionSubWriter that prints out the constructorintroductions
93      * of <code>classdoc</code>.
94      */

95     protected ConstructorIntroductionSubWriter constrIntroductionSubWriter = null;
96     
97     /**
98      * The MethodIntroductionSubWriter that prints out the methodintroductions
99      * of <code>classdoc</code>.
100      */

101     protected MethodIntroductionSubWriter methodIntroductionSubWriter = null;
102     
103     /**
104      * The AdviceSubWriter that prints out the advices
105      * of <code>classdoc</code>.
106      */

107     protected AdviceSubWriter adviceSubWriter = null;
108     
109
110     /**
111      * Construct a ClassWriter from the passed in arguments. This
112      * will instantiate the subwriters to be used.
113      *
114      * @param path the path directory of the html file to generate.
115      * @param filename the html file to generate.
116      * @param classdoc the ClassDoc for which this file will
117      * be generated.
118      * @param prev the ClassDoc preceding <code>classdoc</code>
119      * in order of generation.
120      * @param next the ClassDoc following <code>classdoc</code>
121      * in order of generation.
122      * @param classtree the ClassTree to use.
123      * @param nopackage whether this <code>classdoc</code>'s package
124      * is specified to be documented.
125      */

126     public ClassWriter(String JavaDoc path,
127                        String JavaDoc filename,
128                        ClassDoc classdoc,
129                        ClassDoc prev,
130                        ClassDoc next,
131                        ClassTree classtree,
132                        boolean nopackage)
133         throws IOException JavaDoc, DocletAbortException {
134
135         super(path, filename, classdoc, prev,
136               next, classtree, nopackage);
137
138         // Construct the subwriters just for ClassDocs
139
// We want our superclass to delegate to our subwriters delegate,
140
// but we want to call our subwriters. So we set our superclasses
141
// subwriters to our subwriters delegates.
142
ourMethodSubWriter = new MethodSubWriter(this, classdoc);
143         methodSubWriter = (com.sun.tools.doclets.standard.MethodSubWriter)
144             ourMethodSubWriter.del();
145         constrSubWriter = (com.sun.tools.doclets.standard.ConstructorSubWriter)
146             (ourConstrSubWriter = new ConstructorSubWriter(this, classdoc)).del();
147         fieldSubWriter = (com.sun.tools.doclets.standard.FieldSubWriter)
148             (ourFieldSubWriter = new FieldSubWriter(this, classdoc)).del();
149         innerSubWriter = (com.sun.tools.doclets.standard.ClassSubWriter)
150             (ourInnerSubWriter = new ClassSubWriter(this, classdoc)).del();
151
152         if (classdoc instanceof org.aspectj.ajdoc.ClassDoc) {
153             pointcutSubWriter =
154                 new PointcutSubWriter(this, (org.aspectj.ajdoc.ClassDoc)classdoc);
155         }
156
157         // If we've been passed an AspectDoc, create the AspectJ-specfic
158
// subwriters
159
if (classdoc instanceof AspectDoc) {
160             AspectDoc ad = (AspectDoc)classdoc;
161             superIntroductionSubWriter = new SuperIntroductionSubWriter(this, ad);
162             fieldIntroductionSubWriter = new FieldIntroductionSubWriter(this, ad);
163             constrIntroductionSubWriter = new ConstructorIntroductionSubWriter(this, ad);
164             methodIntroductionSubWriter = new MethodIntroductionSubWriter(this, ad);
165             adviceSubWriter = new AdviceSubWriter(this, ad);
166         }
167     }
168
169     public static void generate(ClassDoc classdoc,
170                                 ClassDoc prev,
171                                 ClassDoc next,
172                                 ClassTree classtree,
173                                 boolean nopackage)
174         throws DocletAbortException {
175         ClassWriter cw = null;
176         String JavaDoc path = DirectoryManager.getDirectoryPath
177             (classdoc.containingPackage());
178         String JavaDoc filename = classdoc.name() + ".html";
179         try {
180             (cw = new ClassWriter(path, filename, classdoc,
181                                   prev, next, classtree, nopackage)).
182                 generateClassFile();
183         } catch (IOException JavaDoc e) {
184             Standard.configuration().standardmessage.
185                 error("doclet.exception_encountered", e+"", filename);
186             throw new DocletAbortException();
187         } finally {
188             if (cw != null) cw.close();
189         }
190     }
191
192     /**
193      * Prints the header of the class -- which is one
194      * of <code>class</code>, <code>interface</code> or
195      * <code>aspect</code> with the name <code>title</code>.
196      *
197      * @param title the name of the class.
198      */

199     public void printHeader(String JavaDoc title) {
200         int ispace = title.indexOf(' ');
201         if (ispace != -1) {
202             title = Statics.type(classdoc) + title.substring(ispace);
203         }
204         super.printHeader(title);
205     }
206
207     /*
208      * This is set up to intercept calls to print out
209      * the correct type of classdoc before we automatically
210      * print 'class' or 'interface'.
211      */

212
213     private boolean h2warn = false;
214
215     /**
216      * If we've started to print a h2 heading, we're
217      * printing the name of the class so get ready to
218      * to intercept the call.
219      */

220     public void h2() {
221         h2warn = true;
222         super.h2();
223     }
224
225     /**
226      * After printing the class declaration with the h2 heading
227      * turn off the h2 warning.
228      */

229     public void h2End() {
230         h2warn = false;
231         super.h2End();
232     }
233
234     /**
235      * This is where we intercept the call to print so
236      * we can print the correct type.
237      */

238     public void print(String JavaDoc str) {
239         if (h2warn) {
240             int ispace = str.indexOf(' ');
241             if (ispace != -1 && str.charAt(0) == 'C') {
242                 str = Statics.type(classdoc) + str.substring(ispace);
243             }
244         }
245         super.print(str);
246     }
247
248     /**
249      * Print the members summary for our AspectJ subwriters.
250      */

251     protected void printAspectJSummary() {
252         printMembersSummary(superIntroductionSubWriter);
253         printMembersSummary(fieldIntroductionSubWriter);
254         printMembersSummary(constrIntroductionSubWriter);
255         printMembersSummary(methodIntroductionSubWriter);
256         printMembersSummary(pointcutSubWriter);
257         printMembersSummary(adviceSubWriter);
258     }
259
260     /**
261      * Formats the output correctly for a member summary.
262      *
263      * @param mw the AbstractSubWriter to use.
264      */

265     protected final void printMembersSummary(AbstractSubWriter mw) {
266         if (mw != null) {
267             println();
268             println("<!-- === " + getText(mw.navKey()) + " SUMMARY === -->");
269             println();
270             mw.printMembersSummary();
271         }
272     }
273
274     /**
275      * Print the members detail for our AspectJ subwriters.
276      */

277     protected void printAspectJDetail() {
278         printMembersDetail(superIntroductionSubWriter);
279         printMembersDetail(fieldIntroductionSubWriter);
280         printMembersDetail(constrIntroductionSubWriter);
281         printMembersDetail(methodIntroductionSubWriter);
282         printMembersDetail(pointcutSubWriter);
283         printMembersDetail(adviceSubWriter);
284     }
285
286     /**
287      * Formats the output correctly for a member detail.
288      *
289      * @param mw the AbstractSubWriter to use.
290      */

291     protected final void printMembersDetail(AbstractSubWriter mw) {
292         if (mw != null) {
293             println("<!-- ===" + getText(mw.navKey()) + " DETAIL === -->");
294             println();
295             mw.printMembers();
296             println();
297         }
298     }
299
300     //TODO: Just need to make sure 'aspect; shows up and
301
//TODO not 'class'
302
protected void printClassDescription() {
303         boolean isInterface = classdoc.isInterface();
304         boolean isAspect = classdoc instanceof AspectDoc;
305         dl();
306         dt();
307
308         print(classdoc.modifiers() + " ");
309
310         if (!isInterface) {
311             print(isAspect ? "aspect " : "class ");
312         }
313         bold(classdoc.name());
314
315         if (!isInterface) {
316             ClassDoc superclass = classdoc.superclass();
317             if (superclass != null) {
318                 dt();
319                 print("extends ");
320                 printClassLink(superclass);
321                 printIntroducedSuper(superclass);
322             }
323         }
324
325         ClassDoc[] implIntfacs = classdoc.interfaces();
326         if (implIntfacs != null && implIntfacs.length > 0) {
327             dt();
328             print(isInterface? "extends " : "implements ");
329             for (int i = 0; i < implIntfacs.length; i++) {
330                 if (i > 0) print(", ");
331                 printClassLink(implIntfacs[i]);
332                 printIntroducedSuper(implIntfacs[i]);
333             }
334         }
335         if (isAspect) {
336             AspectDoc ad = (AspectDoc)classdoc;
337             OfClauseDoc ofClause = ad.ofClause();
338             if (ofClause != null) {
339                 dt();
340                 if (ofClause.kind() == OfClauseDoc.Kind.EACH_CFLOW) {
341                     print("percflow(..)");
342                 } else if (ofClause.kind() == OfClauseDoc.Kind.EACH_JVM) {
343                     print("issingleton()");
344                 } else if (ofClause.kind() == OfClauseDoc.Kind.EACH_OBJECT) {
345                     print("pertarget(");
346                     printClassLinks(((OfEachObjectDoc)ofClause).instances());
347                     print(")");
348                 }
349             }
350             AspectDoc[] dominatees = ad.dominatees();
351             if (dominatees != null && dominatees.length > 0) {
352                 dt();
353                 print("dominates ");
354                 printClassLinks(dominatees);
355             }
356             AspectDoc[] dominators = ad.dominators();
357             if (dominators != null && dominators.length > 0) {
358                 dt();
359                 print("dominated by ");
360                 printClassLinks(dominators);
361             }
362         }
363         dlEnd();
364     }
365
366     /**
367      * Prints a list of class links separated by commas.
368      *
369      * @param cds array of ClassDoc to be printed.
370      */

371     protected void printClassLinks(ClassDoc[] cds) {
372         if (cds == null || cds.length < 1) return;
373         for (int i = 0; i < cds.length; i++) {
374             if (i > 0) print(", ");
375             if (cds[i] != null) {
376                 printClassLink(cds[i]);
377             }
378         }
379     }
380
381     /**
382      * Prints information about <code>classdoc</code>'s type introduction
383      * if <code>cd</code>'s type was introduced onto <code>classdoc</code>.
384      *
385      * @param cd the ClassDoc being printed.
386      */

387     protected void printIntroducedSuper(ClassDoc cd) {
388         IntroducedSuperDoc[] intros =
389             ((org.aspectj.ajdoc.ClassDoc)classdoc).introducers();
390         if (null != intros) {
391             for (int i = 0; i < intros.length; i++) {
392                 IntroducedSuperDoc intro = intros[i];
393                 org.aspectj.ajdoc.Type[] types = intro.types();
394                 for (int j = 0; j < types.length; j++) {
395                     if (types[j].equals(cd)) {
396                         print(' ');
397                         printText("doclet.by_parens",
398                                   getClassLink
399                                   (intro.containingClass(),
400                                    superIntroductionSubWriter.link(intro),
401                                    "introduced"),
402                                   getClassLink(intro.containingClass()));
403                         break;
404                     }
405                 }
406             }
407         }
408     }
409
410     /**
411      * Print the navSummaryLink for all the AspectJ subwriters.
412      */

413     protected void navAspectJSummaryLinks() {
414         navSummaryLink(superIntroductionSubWriter);
415         navSummaryLink(fieldIntroductionSubWriter);
416         navSummaryLink(constrIntroductionSubWriter);
417         navSummaryLink(methodIntroductionSubWriter);
418         navSummaryLink(pointcutSubWriter);
419         navSummaryLink(adviceSubWriter);
420     }
421
422     /**
423      * Prints the navSummaryLink correctly.
424      *
425      * @param mw AbstractSubWriter to invoke.
426      */

427     protected final void navSummaryLink(AbstractSubWriter mw) {
428         if (mw != null) {
429             mw.navSummaryLink();
430             _navGap();
431         }
432     }
433
434     /**
435      * Print the navDetailLink for all the AspectJ subwriters.
436      */

437     protected void navAspectJDetailLinks() {
438         navDetailLink(superIntroductionSubWriter);
439         navDetailLink(fieldIntroductionSubWriter);
440         navDetailLink(constrIntroductionSubWriter);
441         navDetailLink(methodIntroductionSubWriter);
442         navDetailLink(pointcutSubWriter);
443         navDetailLink(adviceSubWriter);
444     }
445
446     /**
447      * Prints the navDetailLink correctly.
448      *
449      * @param mw AbstractSubWriter to invoke.
450      */

451     protected final void navDetailLink(AbstractSubWriter mw) {
452         if (mw != null) {
453             mw.navDetailLink();
454             _navGap();
455         }
456     }
457
458     /*
459      * A hack... I'll explain later, if you need to change
460      * this mail jeffrey_palm@hotmail.com.
461      */

462
463     protected final void _navGap() { super.navGap(); }
464
465     protected int navstate = 0;
466     protected void navGap() {
467         _navGap();
468         if (navstate == 1) {
469             navAspectJSummaryLinks();
470             navstate++;
471         } else if (navstate == 3) {
472             navAspectJDetailLinks();
473             navstate++;
474         }
475     }
476
477     protected void printEnclosingClassInfo() {
478         super.printEnclosingClassInfo();
479         printAdvisorInfo();
480         printAdviseeInfo();
481     }
482
483     protected void printAdviseeInfo() {
484         if (!(classdoc instanceof AspectDoc)) return;
485         AspectDoc ad = (AspectDoc)classdoc;
486         Set JavaDoc set = new TreeSet JavaDoc();
487         AdviceDoc[] as = ad.advice();
488         if (as != null) {
489             for (int i = 0; i < as.length; i++) {
490                 ExecutableMemberDoc[] crosscuts = as[i].crosscuts();
491                 if (null != crosscuts) {
492                     for (int j = 0; j < crosscuts.length; j++) {
493                         if (null != crosscuts[j]) {
494                             set.add(crosscuts[j].containingClass());
495                         }
496                     }
497                 }
498             }
499         }
500         IntroductionDoc[] is = ad.introductions();
501         if (null != is) {
502             for (int i = 0 ; i < is.length; i++) {
503                 ClassDoc[] targets = is[i].targets();
504                 for (int j = 0; j < targets.length; j++) {
505                     set.add(targets[j]);
506                 }
507             }
508             printInfo(set, "doclet.All_Advisees");
509         }
510     }
511
512     protected void printAdvisorInfo() {
513         Set JavaDoc set = new TreeSet JavaDoc();
514         set.addAll(advisors(classdoc.fields()));
515         set.addAll(advisors(classdoc.methods()));
516         set.addAll(advisors(classdoc.constructors()));
517         printInfo(set, "doclet.All_Advisors");
518     }
519
520     protected void printInfo(Collection JavaDoc classdocs, String JavaDoc str) {
521         if ((null != classdocs) && (classdocs.size() > 0)) {
522             printInfoHeader();
523             boldText(str);
524             dd();
525             for (Iterator JavaDoc i = classdocs.iterator(); i.hasNext();) {
526                 printClassLink((ClassDoc)i.next());
527                 if (i.hasNext()) print(", ");
528             }
529             ddEnd();
530             dlEnd();
531         }
532     }
533
534     protected final Collection JavaDoc advisors(final MemberDoc[] ms) {
535         List JavaDoc list = new ArrayList JavaDoc();
536         if (null != ms) {
537             for (int i = 0 ; i < ms.length; i++) {
538                 IntroducedDoc id =
539                     ((org.aspectj.ajdoc.MemberDoc)ms[i]).introduced();
540                 if (id != null) list.add(id.containingClass());
541                 if (ms[i] instanceof org.aspectj.ajdoc.ExecutableMemberDoc) {
542                     AdviceDoc[] as =
543                         ((org.aspectj.ajdoc.ExecutableMemberDoc)ms[i]).advice();
544                     for (int j = 0; j < as.length; j++) {
545                         list.add(as[j].containingClass());
546                     }
547                 }
548             }
549         }
550         return list;
551     }
552 }
553
554
555
Popular Tags