src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java

changeset 1
9a66ca7c79fa
child 182
47a62d8d98b4
equal deleted inserted replaced
-1:000000000000 1:9a66ca7c79fa
1 /*
2 * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.doclets.formats.html;
27
28 import com.sun.tools.doclets.internal.toolkit.*;
29 import com.sun.tools.doclets.internal.toolkit.util.*;
30 import com.sun.tools.doclets.internal.toolkit.builders.*;
31 import com.sun.javadoc.*;
32
33 import java.util.*;
34 import com.sun.tools.doclets.internal.toolkit.taglets.*;
35
36 /**
37 * Generate the Class Information Page.
38 * @see com.sun.javadoc.ClassDoc
39 * @see java.util.Collections
40 * @see java.util.List
41 * @see java.util.ArrayList
42 * @see java.util.HashMap
43 *
44 * @author Atul M Dambalkar
45 * @author Robert Field
46 */
47 public class ClassWriterImpl extends SubWriterHolderWriter
48 implements ClassWriter {
49
50 protected ClassDoc classDoc;
51
52 protected ClassTree classtree;
53
54 protected ClassDoc prev;
55
56 protected ClassDoc next;
57
58 /**
59 * @param classDoc the class being documented.
60 * @param prevClass the previous class that was documented.
61 * @param nextClass the next class being documented.
62 * @param classTree the class tree for the given class.
63 */
64 public ClassWriterImpl (ClassDoc classDoc,
65 ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
66 throws Exception {
67 super(ConfigurationImpl.getInstance(),
68 DirectoryManager.getDirectoryPath(classDoc.containingPackage()),
69 classDoc.name() + ".html",
70 DirectoryManager.getRelativePath(classDoc.containingPackage().name()));
71 this.classDoc = classDoc;
72 configuration.currentcd = classDoc;
73 this.classtree = classTree;
74 this.prev = prevClass;
75 this.next = nextClass;
76 }
77
78 /**
79 * Print this package link
80 */
81 protected void navLinkPackage() {
82 navCellStart();
83 printHyperLink("package-summary.html", "",
84 configuration.getText("doclet.Package"), true, "NavBarFont1");
85 navCellEnd();
86 }
87
88 /**
89 * Print class page indicator
90 */
91 protected void navLinkClass() {
92 navCellRevStart();
93 fontStyle("NavBarFont1Rev");
94 boldText("doclet.Class");
95 fontEnd();
96 navCellEnd();
97 }
98
99 /**
100 * Print class use link
101 */
102 protected void navLinkClassUse() {
103 navCellStart();
104 printHyperLink("class-use/" + filename, "",
105 configuration.getText("doclet.navClassUse"), true, "NavBarFont1");
106 navCellEnd();
107 }
108
109 /**
110 * Print previous package link
111 */
112 protected void navLinkPrevious() {
113 if (prev == null) {
114 printText("doclet.Prev_Class");
115 } else {
116 printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, prev, "",
117 configuration.getText("doclet.Prev_Class"), true));
118 }
119 }
120
121 /**
122 * Print next package link
123 */
124 protected void navLinkNext() {
125 if (next == null) {
126 printText("doclet.Next_Class");
127 } else {
128 printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, next, "",
129 configuration.getText("doclet.Next_Class"), true));
130 }
131 }
132
133 /**
134 * {@inheritDoc}
135 */
136 public void writeHeader(String header) {
137 String pkgname = (classDoc.containingPackage() != null)?
138 classDoc.containingPackage().name(): "";
139 String clname = classDoc.name();
140 printHtmlHeader(clname,
141 configuration.metakeywords.getMetaKeywords(classDoc), true);
142 printTop();
143 navLinks(true);
144 hr();
145 println("<!-- ======== START OF CLASS DATA ======== -->");
146 h2();
147 if (pkgname.length() > 0) {
148 font("-1"); print(pkgname); fontEnd(); br();
149 }
150 LinkInfoImpl linkInfo = new LinkInfoImpl( LinkInfoImpl.CONTEXT_CLASS_HEADER,
151 classDoc, false);
152 //Let's not link to ourselves in the header.
153 linkInfo.linkToSelf = false;
154 print(header + getTypeParameterLinks(linkInfo));
155 h2End();
156 }
157
158 /**
159 * {@inheritDoc}
160 */
161 public void writeFooter() {
162 println("<!-- ========= END OF CLASS DATA ========= -->");
163 hr();
164 navLinks(false);
165 printBottom();
166 printBodyHtmlEnd();
167 }
168
169 /**
170 * {@inheritDoc}
171 */
172 public void writeClassSignature(String modifiers) {
173 boolean isInterface = classDoc.isInterface();
174 dl();
175 dt();
176 preNoNewLine();
177 writeAnnotationInfo(classDoc);
178 print(modifiers);
179 LinkInfoImpl linkInfo = new LinkInfoImpl(
180 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
181 //Let's not link to ourselves in the signature.
182 linkInfo.linkToSelf = false;
183 String name = classDoc.name() +
184 getTypeParameterLinks(linkInfo);
185 if (configuration().linksource) {
186 printSrcLink(classDoc, name);
187 } else {
188 bold(name);
189 }
190 if (!isInterface) {
191 Type superclass = Util.getFirstVisibleSuperClass(classDoc,
192 configuration());
193 if (superclass != null) {
194 dt();
195 print("extends ");
196 printLink(new LinkInfoImpl(
197 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
198 superclass));
199 }
200 }
201 Type[] implIntfacs = classDoc.interfaceTypes();
202 if (implIntfacs != null && implIntfacs.length > 0) {
203 int counter = 0;
204 for (int i = 0; i < implIntfacs.length; i++) {
205 ClassDoc classDoc = implIntfacs[i].asClassDoc();
206 if (! (classDoc.isPublic() ||
207 Util.isLinkable(classDoc, configuration()))) {
208 continue;
209 }
210 if (counter == 0) {
211 dt();
212 print(isInterface? "extends " : "implements ");
213 } else {
214 print(", ");
215 }
216 printLink(new LinkInfoImpl(
217 LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
218 implIntfacs[i]));
219 counter++;
220 }
221 }
222 dlEnd();
223 preEnd();
224 p();
225 }
226
227 /**
228 * {@inheritDoc}
229 */
230 public void writeClassDescription() {
231 if(!configuration.nocomment) {
232 // generate documentation for the class.
233 if (classDoc.inlineTags().length > 0) {
234 printInlineComment(classDoc);
235 p();
236 }
237 }
238 }
239
240 /**
241 * {@inheritDoc}
242 */
243 public void writeClassTagInfo() {
244 if(!configuration.nocomment) {
245 // Print Information about all the tags here
246 printTags(classDoc);
247 hr();
248 p();
249 } else {
250 hr();
251 }
252 }
253
254 /**
255 * {@inheritDoc}
256 */
257 public void writeClassDeprecationInfo() {
258 hr();
259 Tag[] deprs = classDoc.tags("deprecated");
260 if (Util.isDeprecated(classDoc)) {
261 boldText("doclet.Deprecated");
262 if (deprs.length > 0) {
263 Tag[] commentTags = deprs[0].inlineTags();
264 if (commentTags.length > 0) {
265 space();
266 printInlineDeprecatedComment(classDoc, deprs[0]);
267 }
268 }
269 p();
270 }
271 }
272
273 /**
274 * Generate the indent and get the line image for the class tree.
275 * For user accessibility, the image includes the alt attribute
276 * "extended by". (This method is not intended for a class
277 * implementing an interface, where "implemented by" would be required.)
278 *
279 * indent integer indicating the number of spaces to indent
280 */
281 private void writeStep(int indent) {
282 print(spaces(4 * indent - 2));
283 print("<IMG SRC=\"" + relativepathNoSlash + "/resources/inherit.gif\" " +
284 "ALT=\"" + configuration.getText("doclet.extended_by") + " \">");
285 }
286
287 /**
288 * Print the class hierarchy tree for the given class.
289 * @param type the class to print the hierarchy for.
290 * @return return the amount that should be indented in
291 * the next level of the tree.
292 */
293 private int writeTreeForClassHelper(Type type) {
294 Type sup = Util.getFirstVisibleSuperClass(
295 type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
296 configuration());
297 int indent = 0;
298 if (sup != null) {
299 indent = writeTreeForClassHelper(sup);
300 writeStep(indent);
301 }
302
303 if (type.equals(classDoc)) {
304 String typeParameters = getTypeParameterLinks(
305 new LinkInfoImpl(
306 LinkInfoImpl.CONTEXT_TREE,
307 classDoc, false));
308 if (configuration.shouldExcludeQualifier(
309 classDoc.containingPackage().name())) {
310 bold(type.asClassDoc().name() + typeParameters);
311 } else {
312 bold(type.asClassDoc().qualifiedName() + typeParameters);
313 }
314 } else {
315 print(getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
316 type instanceof ClassDoc ? (ClassDoc) type : type,
317 configuration.getClassName(type.asClassDoc()), false)));
318 }
319 println();
320 return indent + 1;
321 }
322
323 /**
324 * Print the class hierarchy tree for this class only.
325 */
326 public void writeClassTree() {
327 if (! classDoc.isClass()) {
328 return;
329 }
330 pre();
331 writeTreeForClassHelper(classDoc);
332 preEnd();
333 }
334
335 /**
336 * Write the type parameter information.
337 */
338 public void writeTypeParamInfo() {
339 if (classDoc.typeParamTags().length > 0) {
340 dl();
341 dt();
342 TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
343 getTagletWriterInstance(false));
344 print(output.toString());
345 dlEnd();
346 }
347 }
348
349 /**
350 * {@inheritDoc}
351 */
352 public void writeSubClassInfo() {
353 if (classDoc.isClass()) {
354 if (classDoc.qualifiedName().equals("java.lang.Object") ||
355 classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
356 return; // Don't generate the list, too huge
357 }
358 List subclasses = classtree.subs(classDoc, false);
359 if (subclasses.size() > 0) {
360 dl();
361 dt();
362 boldText("doclet.Subclasses");
363 writeClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
364 subclasses);
365 }
366 }
367 }
368
369 /**
370 * {@inheritDoc}
371 */
372 public void writeSubInterfacesInfo() {
373 if (classDoc.isInterface()) {
374 List subInterfaces = classtree.allSubs(classDoc, false);
375 if (subInterfaces.size() > 0) {
376 dl();
377 dt();
378 boldText("doclet.Subinterfaces");
379 writeClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
380 subInterfaces);
381 }
382 }
383 }
384
385 /**
386 * If this is the interface which are the classes, that implement this?
387 */
388 public void writeInterfaceUsageInfo () {
389 if (! classDoc.isInterface()) {
390 return;
391 }
392 if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
393 classDoc.qualifiedName().equals("java.io.Serializable")) {
394 return; // Don't generate the list, too big
395 }
396 List implcl = classtree.implementingclasses(classDoc);
397 if (implcl.size() > 0) {
398 dl();
399 dt();
400 boldText("doclet.Implementing_Classes");
401 writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
402 implcl);
403 }
404 }
405
406 /**
407 * {@inheritDoc}
408 */
409 public void writeImplementedInterfacesInfo() {
410 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
411 // it doesn't walk up the tree like we want it to.
412 List interfaceArray = Util.getAllInterfaces(classDoc, configuration);
413 if (classDoc.isClass() && interfaceArray.size() > 0) {
414 dl();
415 dt();
416 boldText("doclet.All_Implemented_Interfaces");
417 writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
418 interfaceArray);
419 }
420 }
421
422 /**
423 * {@inheritDoc}
424 */
425 public void writeSuperInterfacesInfo() {
426 //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
427 // it doesn't walk up the tree like we want it to.
428 List interfaceArray = Util.getAllInterfaces(classDoc, configuration);
429 if (classDoc.isInterface() && interfaceArray.size() > 0) {
430 dl();
431 dt();
432 boldText("doclet.All_Superinterfaces");
433 writeClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
434 interfaceArray);
435 }
436 }
437
438 /**
439 * Generate links to the given classes.
440 */
441 private void writeClassLinks(int context, List list) {
442 Object[] typeList = list.toArray();
443 //Sort the list to be printed.
444 print(' ');
445 dd();
446 for (int i = 0; i < list.size(); i++) {
447 if (i > 0) {
448 print(", ");
449 }
450 if (typeList[i] instanceof ClassDoc) {
451 printLink(new LinkInfoImpl(context, (ClassDoc)(typeList[i])));
452
453 } else {
454 printLink(new LinkInfoImpl(context, (Type)(typeList[i])));
455 }
456 }
457 ddEnd();
458 dlEnd();
459 }
460
461 protected void navLinkTree() {
462 navCellStart();
463 printHyperLink("package-tree.html", "",
464 configuration.getText("doclet.Tree"), true, "NavBarFont1");
465 navCellEnd();
466 }
467
468 protected void printSummaryDetailLinks() {
469 try {
470 tr();
471 tdVAlignClass("top", "NavBarCell3");
472 font("-2");
473 print(" ");
474 navSummaryLinks();
475 fontEnd();
476 tdEnd();
477 tdVAlignClass("top", "NavBarCell3");
478 font("-2");
479 navDetailLinks();
480 fontEnd();
481 tdEnd();
482 trEnd();
483 } catch (Exception e) {
484 e.printStackTrace();
485 throw new DocletAbortException();
486 }
487 }
488
489 protected void navSummaryLinks() throws Exception {
490 printText("doclet.Summary");
491 space();
492 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
493 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
494 String[] navLinkLabels = new String[] {
495 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
496 "doclet.navMethod"
497 };
498 for (int i = 0; i < navLinkLabels.length; i++ ) {
499 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
500 continue;
501 }
502 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
503 continue;
504 }
505 AbstractMemberWriter writer =
506 ((AbstractMemberWriter) memberSummaryBuilder.
507 getMemberSummaryWriter(i));
508 if (writer == null) {
509 printText(navLinkLabels[i]);
510 } else {
511 writer.navSummaryLink(
512 memberSummaryBuilder.members(i),
513 memberSummaryBuilder.getVisibleMemberMap(i));
514 }
515 if (i < navLinkLabels.length-1) {
516 navGap();
517 }
518 }
519 }
520
521 /**
522 * Method navDetailLinks
523 *
524 * @throws Exception
525 *
526 */
527 protected void navDetailLinks() throws Exception {
528 printText("doclet.Detail");
529 space();
530 MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
531 configuration.getBuilderFactory().getMemberSummaryBuilder(this);
532 String[] navLinkLabels = new String[] {
533 "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
534 "doclet.navMethod"
535 };
536 for (int i = 1; i < navLinkLabels.length; i++ ) {
537 AbstractMemberWriter writer =
538 ((AbstractMemberWriter) memberSummaryBuilder.
539 getMemberSummaryWriter(i));
540 if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
541 continue;
542 }
543 if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
544 continue;
545 }
546 if (writer == null) {
547 printText(navLinkLabels[i]);
548 } else {
549 writer.navDetailLink(memberSummaryBuilder.members(i));
550 }
551 if (i < navLinkLabels.length - 1) {
552 navGap();
553 }
554 }
555 }
556
557 protected void navGap() {
558 space();
559 print('|');
560 space();
561 }
562
563 /**
564 * If this is an inner class or interface, write the enclosing class or
565 * interface.
566 */
567 public void writeNestedClassInfo() {
568 ClassDoc outerClass = classDoc.containingClass();
569 if (outerClass != null) {
570 dl();
571 dt();
572 if (outerClass.isInterface()) {
573 boldText("doclet.Enclosing_Interface");
574 } else {
575 boldText("doclet.Enclosing_Class");
576 }
577 dd();
578 printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, outerClass,
579 false));
580 ddEnd();
581 dlEnd();
582 }
583 }
584
585 /**
586 * Return the classDoc being documented.
587 *
588 * @return the classDoc being documented.
589 */
590 public ClassDoc getClassDoc() {
591 return classDoc;
592 }
593
594 /**
595 * {@inheritDoc}
596 */
597 public void completeMemberSummaryBuild() {
598 p();
599 }
600 }

mercurial