2009-07-17 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / libjava / classpath / tools / gnu / classpath / tools / doclets / htmldoclet / HtmlDoclet.java
blobe49e1c573410f8595b500eca46ebaf9bc69da0ed
1 /* gnu.classpath.tools.doclets.htmldoclet.HtmlDoclet
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 package gnu.classpath.tools.doclets.htmldoclet;
23 import gnu.classpath.tools.IOToolkit;
25 import gnu.classpath.tools.doclets.AbstractDoclet;
26 import gnu.classpath.tools.doclets.DocletConfigurationException;
27 import gnu.classpath.tools.doclets.DocletOption;
28 import gnu.classpath.tools.doclets.DocletOptionFile;
29 import gnu.classpath.tools.doclets.DocletOptionFlag;
30 import gnu.classpath.tools.doclets.DocletOptionString;
31 import gnu.classpath.tools.doclets.PackageGroup;
32 import gnu.classpath.tools.doclets.TagletPrinter;
33 import gnu.classpath.tools.doclets.InlineTagRenderer;
35 import gnu.classpath.tools.doclets.xmldoclet.HtmlRepairer;
37 import gnu.classpath.tools.taglets.GnuExtendedTaglet;
38 import gnu.classpath.tools.taglets.TagletContext;
40 import gnu.classpath.tools.java2xhtml.Java2xhtml;
42 import gnu.classpath.tools.StringToolkit;
44 import com.sun.javadoc.*;
45 import com.sun.tools.doclets.Taglet;
47 import java.io.ByteArrayInputStream;
48 import java.io.File;
49 import java.io.FileInputStream;
50 import java.io.FileNotFoundException;
51 import java.io.FileOutputStream;
52 import java.io.FileReader;
53 import java.io.FileWriter;
54 import java.io.InputStream;
55 import java.io.InputStreamReader;
56 import java.io.IOException;
57 import java.io.OutputStreamWriter;
58 import java.io.PrintWriter;
59 import java.io.StringWriter;
61 import java.net.MalformedURLException;
63 import java.nio.charset.Charset;
65 import java.text.DateFormat;
66 import java.text.MessageFormat;
68 import java.util.Arrays;
69 import java.util.Calendar;
70 import java.util.Collection;
71 import java.util.Date;
72 import java.util.HashMap;
73 import java.util.Iterator;
74 import java.util.LinkedHashSet;
75 import java.util.LinkedList;
76 import java.util.List;
77 import java.util.ListIterator;
78 import java.util.Locale;
79 import java.util.Map;
80 import java.util.Properties;
81 import java.util.Set;
82 import java.util.SortedSet;
83 import java.util.TimeZone;
84 import java.util.TreeSet;
86 public class HtmlDoclet
87 extends AbstractDoclet
88 implements InlineTagRenderer
90 private static String filenameExtension = ".html";
92 /**
93 * Contains ExternalDocSet.
95 private List externalDocSets = new LinkedList();
97 /**
98 * Contains String->ExternalDocSet.
100 private Map packageNameToDocSet = new HashMap();
103 * Cache for version string from resource /version.properties
105 private String docletVersion;
108 * For now, do not output a help page.
110 private static final boolean outputHelpPage = false;
113 * Stores the output encoding (either the one specified using
114 * -charset, or the platform default encoding).
116 private String outputCharset;
118 private void printNavBar(HtmlPage output, String currentPage, ClassDoc currentClass)
120 output.beginDiv(CssClass.NAVBAR_TOP);
122 boolean overviewLevel
123 = ("overview".equals(currentPage)
124 || "full-tree".equals(currentPage)
125 || "index".equals(currentPage)
126 || "split-index".equals(currentPage)
127 || "serialized".equals(currentPage)
128 || "deprecated".equals(currentPage)
129 || "about".equals(currentPage)
132 if (!isSinglePackage()) {
133 if ("overview".equals(currentPage)) {
134 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
135 output.print("Overview");
136 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
138 else {
139 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
140 output.beginAnchor(output.getPathToRoot() + "/overview-summary" + filenameExtension);
141 output.print("Overview");
142 output.endAnchor();
143 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
146 output.print(" ");
149 if (!overviewLevel || isSinglePackage()) {
150 if ("package".equals(currentPage)) {
151 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
152 output.print("Package");
153 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
155 else {
156 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
157 String packageHref;
158 if (isSinglePackage()) {
159 packageHref = output.getPathToRoot() + "/" + getPackageURL(getSinglePackage()) + "package-summary" + filenameExtension;
161 else {
162 packageHref = "package-summary" + filenameExtension;
164 output.beginAnchor(packageHref);
165 output.print("Package");
166 output.endAnchor();
167 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
170 else {
171 output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
172 output.print("Package");
173 output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
176 if (optionUse.getValue() || optionLinkSource.getValue()) {
177 output.print(" ");
179 if (null != currentClass) {
180 if ("class".equals(currentPage)) {
181 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
182 output.print("Class");
183 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
185 else {
186 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
187 output.beginAnchor(currentClass.name() + filenameExtension);
188 output.print("Class");
189 output.endAnchor();
190 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
193 else {
194 output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
195 output.print("Class");
196 output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
199 if (optionUse.getValue()) {
200 output.print(" ");
202 if (null != currentClass) {
203 if ("uses".equals(currentPage)) {
204 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
205 output.print("Use");
206 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
208 else {
209 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
210 output.beginAnchor(currentClass.name() + "-uses" + filenameExtension);
211 output.print("Use");
212 output.endAnchor();
213 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
216 else {
217 output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
218 output.print("Use");
219 output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
223 if (optionLinkSource.getValue()) {
224 output.print(" ");
227 if ("source".equals(currentPage)) {
228 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
229 output.print("Source");
230 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
232 else {
234 if (null != currentClass) {
236 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
237 String targetClassName = currentClass.name();
238 String targetAnchor = "";
239 if (null != currentClass.containingClass()) {
240 targetClassName = getOuterClassDoc(currentClass).name();
241 targetAnchor = "#line." + currentClass.position().line();
243 output.beginAnchor(targetClassName + "-source" + filenameExtension + targetAnchor);
244 output.print("Source");
245 output.endAnchor();
246 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
248 else {
249 output.beginSpan(CssClass.NAVBAR_ITEM_DISABLED);
250 output.print("Source");
251 output.endSpan(CssClass.NAVBAR_ITEM_DISABLED);
258 if (!optionNoTree.getValue()) {
259 output.print(" ");
261 if ("full-tree".equals(currentPage)
262 || "package-tree".equals(currentPage)) {
263 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
264 output.print("Tree");
265 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
267 else {
268 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
269 String treeHref;
270 if (isSinglePackage() && overviewLevel) {
271 treeHref = getPackageURL(getSinglePackage()) + "tree" + filenameExtension;
273 else {
274 treeHref = "tree" + filenameExtension;
277 output.beginAnchor(treeHref);
278 output.print("Tree");
279 output.endAnchor();
280 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
284 output.print(" ");
286 String indexName;
287 if (optionSplitIndex.getValue()) {
288 indexName = "alphaindex-1";
290 else {
291 indexName = "alphaindex";
294 if ("index".equals(currentPage) || "split-index".equals(currentPage)) {
295 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
296 output.print("Index");
297 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
299 else {
300 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
301 output.beginAnchor(output.getPathToRoot() + "/" + indexName + filenameExtension);
302 output.print("Index");
303 output.endAnchor();
304 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
307 if (!optionNoDeprecatedList.getValue()) {
308 output.print(" ");
310 if ("deprecated".equals(currentPage)) {
311 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
312 output.print("Deprecated");
313 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
315 else {
316 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
317 output.beginAnchor(output.getPathToRoot() + "/deprecated" + filenameExtension);
318 output.print("Deprecated");
319 output.endAnchor();
320 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
324 if (outputHelpPage) {
325 if (!optionNoHelp.getValue()) {
326 output.print(" ");
328 if ("help".equals(currentPage)) {
329 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
330 output.print("Help");
331 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
333 else {
334 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
335 output.beginAnchor(output.getPathToRoot() + "/help" + filenameExtension);
336 output.print("Help");
337 output.endAnchor();
338 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
343 output.print(" ");
345 if ("about".equals(currentPage)) {
346 output.beginSpan(CssClass.NAVBAR_ITEM_ACTIVE);
347 output.print("About");
348 output.endSpan(CssClass.NAVBAR_ITEM_ACTIVE);
350 else {
351 output.beginSpan(CssClass.NAVBAR_ITEM_ENABLED);
352 output.beginAnchor(output.getPathToRoot() + "/about" + filenameExtension);
353 output.print("About");
354 output.endAnchor();
355 output.endSpan(CssClass.NAVBAR_ITEM_ENABLED);
358 output.endDiv(CssClass.NAVBAR_TOP);
361 private void printNavBarTopRow(HtmlPage output, String currentPage, ClassDoc currentClass)
363 output.beginRow();
364 output.beginCell(CssClass.NAVBAR_TOP);
365 printNavBar(output, currentPage, currentClass);
366 output.endCell();
367 if (null != optionHeader.getValue()) {
368 output.beginCell(CssClass.NAVBAR_TOP_HEADER);
369 output.print(replaceDocRoot(output, optionHeader.getValue()));
370 output.endCell();
372 output.endRow();
375 private void printNavBarTopNaviCell(HtmlPage output)
377 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
378 output.beginAnchor(output.getPathToRoot() + "/index" + filenameExtension, "Show in a frameset", "_top");
379 output.print("Frames");
380 output.endAnchor();
381 output.print(" | ");
383 output.beginAnchor(output.getFile().getName(), "Show without frames", "_top");
384 output.print("No Frames");
385 output.endAnchor();
386 output.print(" ");
388 output.endCell();
391 private void printNavBarTop(HtmlPage output, String currentPage)
393 printNavBarTop(output, currentPage, null, null, null);
396 private void printNavBarTop(HtmlPage output, String currentPage,
397 ClassDoc currentClass, Object prev, Object next)
399 if (!optionNoNavBar.getValue()) {
400 output.beginTable(CssClass.NAVBAR_TOP);
401 printNavBarTopRow(output, currentPage, currentClass);
402 output.beginRow();
403 if ("class".equals(currentPage)) {
404 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
405 ClassDoc prevClass = (ClassDoc)prev;
406 ClassDoc nextClass = (ClassDoc)next;
407 if (null != prevClass) {
408 output.anchor(getClassDocURL(output, prevClass), "Prev Class");
410 else {
411 output.print("Prev Class");
413 output.print(" | ");
414 if (null != nextClass) {
415 output.anchor(getClassDocURL(output, nextClass), "Next Class");
417 else {
418 output.print("Next Class");
420 output.endCell();
422 else if ("split-index".equals(currentPage)) {
423 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
424 Integer prevLetter = (Integer)prev;
425 Integer nextLetter = (Integer)next;
426 if (null != prevLetter) {
427 output.anchor("alphaindex-" + prevLetter + filenameExtension, "Prev Letter");
429 else {
430 output.print("Prev Letter");
432 output.print(" | ");
433 if (null != nextLetter) {
434 output.anchor("alphaindex-" + nextLetter + filenameExtension, "Next Letter");
436 else {
437 output.print("Next Letter");
439 output.endCell();
441 else {
442 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
443 output.endCell();
446 printNavBarTopNaviCell(output);
447 output.endRow();
449 if ("class".equals(currentPage)) {
450 output.beginRow();
452 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
453 output.print("Summary: ");
455 if (currentClass.innerClasses().length > 0) {
456 output.anchor("#summary-inner", "Nested");
458 else {
459 output.print("Nested");
462 output.print(" | ");
464 if (currentClass.fields().length > 0) {
465 output.anchor("#summary-fields", "Field");
467 else {
468 output.print("Field");
471 output.print(" | ");
473 if (currentClass.methods().length > 0) {
474 output.anchor("#summary-methods", "Method");
476 else {
477 output.print("Method");
480 output.print(" | ");
482 if (currentClass.constructors().length > 0) {
483 output.anchor("#summary-constructors", "Constr");
485 else {
486 output.print("Constr");
489 output.endCell();
491 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
492 output.print("Detail: ");
494 if (currentClass.innerClasses().length > 0) {
495 output.anchor("#detail-inner", "Nested");
497 else {
498 output.print("Nested");
501 output.print(" | ");
503 if (currentClass.fields().length > 0) {
504 output.anchor("#detail-fields", "Field");
506 else {
507 output.print("Field");
510 output.print(" | ");
512 if (currentClass.methods().length > 0) {
513 output.anchor("#detail-methods", "Method");
515 else {
516 output.print("Method");
519 output.print(" | ");
521 if (currentClass.constructors().length > 0) {
522 output.anchor("#detail-constructors", "Constr");
524 else {
525 output.print("Constr");
528 output.endCell();
529 output.endRow();
531 output.endTable();
535 private void printNavBarTopPackage(HtmlPage output, String currentPage,
536 PackageDoc prevPackage, PackageDoc nextPackage)
538 if (!optionNoNavBar.getValue()) {
539 output.beginTable(CssClass.NAVBAR_TOP);
540 printNavBarTopRow(output, currentPage, null);
542 output.beginRow();
543 output.beginCell(CssClass.NAVBAR_TOP_NAVI);
544 if (null != prevPackage) {
545 output.anchor(output.getPathToRoot() + "/" + getPackageURL(prevPackage) + "package-summary" + filenameExtension, "Prev Package");
547 else {
548 output.print("Prev Package");
550 output.print(" | ");
551 if (null != nextPackage) {
552 output.anchor(output.getPathToRoot() + "/" + getPackageURL(nextPackage) + "package-summary" + filenameExtension, "Next Package");
554 else {
555 output.print("Next Package");
557 output.endCell();
559 printNavBarTopNaviCell(output);
560 output.endRow();
562 output.endTable();
566 private void printNavBarBottom(HtmlPage output, String currentPage)
568 printNavBarBottom(output, currentPage, null);
571 private void printNavBarBottom(HtmlPage output, String currentPage, ClassDoc currentClass)
573 if ("class".equals(currentPage)) {
574 String boilerplate = null;
575 Tag[] boilerplateTags = getOuterClassDoc(currentClass).tags("@boilerplate");
576 if (boilerplateTags.length > 0) {
577 boilerplate = boilerplateTags[0].text();
579 if (null != boilerplate) {
580 output.hr();
581 output.beginDiv(CssClass.CLASS_BOILERPLATE);
582 output.print(boilerplate);
583 output.endDiv(CssClass.CLASS_BOILERPLATE);
584 output.hr();
588 if (!optionNoNavBar.getValue()) {
589 output.beginDiv(CssClass.NAVBAR_BOTTOM_SPACER);
590 output.print(" ");
591 output.endDiv(CssClass.NAVBAR_BOTTOM_SPACER);
592 output.beginTable(CssClass.NAVBAR_BOTTOM);
593 output.beginRow();
594 output.beginCell();
595 printNavBar(output, currentPage, currentClass);
596 output.endCell();
597 if (null != optionFooter.getValue()) {
598 output.beginCell();
599 output.print(replaceDocRoot(output, optionFooter.getValue()));
600 output.endCell();
602 output.endRow();
603 output.endTable();
606 if (null != optionBottom.getValue()) {
607 output.hr();
608 output.print(replaceDocRoot(output, optionBottom.getValue()));
612 private void printPackagePageClasses(HtmlPage output, ClassDoc[] classDocs, String header)
614 if (classDocs.length > 0) {
615 output.beginDiv(CssClass.TABLE_CONTAINER);
616 output.beginTable(CssClass.PACKAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
617 output.rowDiv(CssClass.TABLE_HEADER, header);
619 for (int i=0; i<classDocs.length; ++i) {
620 ClassDoc classDoc = classDocs[i];
621 if (classDoc.isIncluded()) {
622 output.beginRow();
624 output.beginCell(CssClass.PACKAGE_SUMMARY_LEFT);
625 printType(output, classDoc);
626 output.endCell();
628 output.beginCell(CssClass.PACKAGE_SUMMARY_RIGHT);
629 printTags(output, classDoc, classDoc.firstSentenceTags(), true);
630 output.endCell();
631 output.endRow();
634 output.endTable();
635 output.endDiv(CssClass.TABLE_CONTAINER);
636 output.print("\n");
640 private void printPackagesListFile()
641 throws IOException
643 PrintWriter out
644 = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(getTargetDirectory(),
645 "package-list")),
646 "UTF-8"));
648 PackageDoc[] packages = getRootDoc().specifiedPackages();
649 for (int i=0; i<packages.length; ++i) {
650 String packageName = packages[i].name();
651 if (packageName.length() > 0) {
652 out.println(packageName);
656 out.close();
659 private void printPackagePage(File packageDir, String pathToRoot,
660 PackageDoc packageDoc,
661 PackageDoc prevPackageDoc,
662 PackageDoc nextPackageDoc)
663 throws IOException
665 HtmlPage output = newHtmlPage(new File(packageDir, "package-summary" + filenameExtension),
666 pathToRoot);
668 Set keywords = new LinkedHashSet();
669 keywords.add(packageDoc.name() + " packages");
671 output.beginPage(getPageTitle(packageDoc.name()), getOutputCharset(),
672 keywords, getStylesheets());
673 output.beginBody(CssClass.BODY_CONTENT_PACKAGE);
674 printNavBarTopPackage(output, "package", prevPackageDoc, nextPackageDoc);
676 output.beginDiv(CssClass.PACKAGE_TITLE);
677 output.print("Package ");
678 if (packageDoc.name().length() > 0) {
679 output.print(packageDoc.name());
681 else {
682 output.print("&lt;Unnamed&gt;");
684 output.endDiv(CssClass.PACKAGE_TITLE);
686 output.beginDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
687 printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
688 output.endDiv(CssClass.PACKAGE_DESCRIPTION_TOP);
690 printPackagePageClasses(output, packageDoc.interfaces(),
691 "Interface Summary");
692 printPackagePageClasses(output, packageDoc.ordinaryClasses(),
693 "Class Summary");
694 printPackagePageClasses(output, packageDoc.exceptions(),
695 "Exception Summary");
696 printPackagePageClasses(output, packageDoc.errors(),
697 "Error Summary");
699 output.anchorName("description");
700 output.beginDiv(CssClass.PACKAGE_DESCRIPTION_FULL);
701 printTags(output, packageDoc, packageDoc.inlineTags(), false);
702 output.endDiv(CssClass.PACKAGE_DESCRIPTION_FULL);
704 printNavBarBottom(output, "package");
705 output.endBody();
706 output.endPage();
707 output.close();
710 static class TreeNode
711 implements Comparable
713 ClassDoc classDoc;
714 SortedSet children = new TreeSet();
716 TreeNode(ClassDoc classDoc) {
717 TreeNode.this.classDoc = classDoc;
720 public boolean equals(Object other)
722 return classDoc.equals(((TreeNode)other).classDoc);
725 public int compareTo(Object other)
727 return classDoc.compareTo(((TreeNode)other).classDoc);
730 public int hashCode()
732 return classDoc.hashCode();
736 private TreeNode addClassTreeNode(Map treeMap, ClassDoc classDoc)
738 TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
739 if (null == node) {
740 node = new TreeNode(classDoc);
741 treeMap.put(classDoc.qualifiedName(), node);
743 ClassDoc superClassDoc = (ClassDoc)classDoc.superclass();
744 if (null != superClassDoc) {
745 TreeNode parentNode = addClassTreeNode(treeMap, superClassDoc);
746 parentNode.children.add(node);
749 return node;
752 private TreeNode addInterfaceTreeNode(Map treeMap, ClassDoc classDoc)
754 TreeNode node = (TreeNode)treeMap.get(classDoc.qualifiedName());
755 if (null == node) {
756 node = new TreeNode(classDoc);
757 treeMap.put(classDoc.qualifiedName(), node);
759 ClassDoc[] superInterfaces = classDoc.interfaces();
760 if (null != superInterfaces && superInterfaces.length > 0) {
761 for (int i=0; i<superInterfaces.length; ++i) {
762 TreeNode parentNode = addInterfaceTreeNode(treeMap, superInterfaces[i]);
763 parentNode.children.add(node);
766 else {
767 TreeNode rootNode = (TreeNode)treeMap.get("<root>");
768 if (null == rootNode) {
769 rootNode = new TreeNode(null);
770 treeMap.put("<root>", rootNode);
772 rootNode.children.add(node);
775 return node;
778 private void printPackageTreeRec(HtmlPage output, TreeNode node, TreeNode parentNode)
780 output.beginElement("li", "class", "node");
781 output.beginElement("div");
782 if (node.classDoc.isIncluded()) {
783 String packageName = node.classDoc.containingPackage().name();
784 if (packageName.length() > 0) {
785 output.print(packageName);
786 output.print(".");
788 output.beginSpan(CssClass.TREE_LINK);
789 printType(output, node.classDoc);
790 output.endSpan(CssClass.TREE_LINK);
792 else {
793 output.print(possiblyQualifiedName(node.classDoc));
795 ClassDoc[] interfaces = node.classDoc.interfaces();
796 ClassDoc parentClassDoc = null;
797 if (null != parentNode) {
798 parentClassDoc = parentNode.classDoc;
800 if (interfaces.length > 0
801 && !(interfaces.length == 1 && interfaces[0].equals(parentClassDoc))) {
802 if (node.classDoc.isInterface()) {
803 output.print(" (also implements ");
805 else {
806 output.print(" (implements ");
809 boolean firstItem = true;
810 for (int i=0; i<interfaces.length; ++i) {
811 ClassDoc implemented = interfaces[i];
812 if (!implemented.equals(parentClassDoc)) {
813 if (!firstItem) {
814 output.print(", ");
816 firstItem = false;
817 if (implemented.isIncluded()) {
818 output.print(implemented.containingPackage().name());
819 output.print(".");
820 printType(output, implemented);
822 else {
823 output.print(possiblyQualifiedName(implemented));
827 output.print(")");
830 output.endElement("div");
831 output.endElement("li");
832 if (!node.children.isEmpty()) {
833 output.beginElement("li", "class", "level");
834 output.beginElement("ul");
835 Iterator it = node.children.iterator();
836 while (it.hasNext()) {
837 TreeNode child = (TreeNode)it.next();
838 printPackageTreeRec(output, child, node);
840 output.endElement("ul");
841 output.endElement("li");
845 private void printClassTree(HtmlPage output, ClassDoc[] classDocs)
847 Map classTreeMap = new HashMap();
849 for (int i=0; i<classDocs.length; ++i) {
850 ClassDoc classDoc = classDocs[i];
851 if (!classDoc.isInterface()) {
852 addClassTreeNode(classTreeMap, classDoc);
856 TreeNode root = (TreeNode)classTreeMap.get("java.lang.Object");
857 if (null != root) {
858 output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Class Hierarchy");
859 output.beginDiv(CssClass.PACKAGE_TREE);
860 printPackageTreeRec(output, root, null);
861 output.endDiv(CssClass.PACKAGE_TREE);
865 private void printInterfaceTree(HtmlPage output, ClassDoc[] classDocs)
867 Map interfaceTreeMap = new HashMap();
869 for (int i=0; i<classDocs.length; ++i) {
870 ClassDoc classDoc = classDocs[i];
871 if (classDoc.isInterface()) {
872 addInterfaceTreeNode(interfaceTreeMap, classDoc);
876 TreeNode interfaceRoot = (TreeNode)interfaceTreeMap.get("<root>");
877 if (null != interfaceRoot) {
878 Iterator it = interfaceRoot.children.iterator();
879 if (it.hasNext()) {
880 output.div(CssClass.PACKAGE_TREE_SECTION_TITLE, "Interface Hierarchy");
881 output.beginDiv(CssClass.PACKAGE_TREE);
882 while (it.hasNext()) {
883 TreeNode node = (TreeNode)it.next();
884 printPackageTreeRec(output, node, null);
886 output.endDiv(CssClass.PACKAGE_TREE);
892 private void printPackageTreePage(File packageDir, String pathToRoot, PackageDoc packageDoc)
893 throws IOException
895 HtmlPage output = newHtmlPage(new File(packageDir,
896 "tree" + filenameExtension),
897 pathToRoot);
898 output.beginPage(getPageTitle(packageDoc.name() + " Hierarchy"),
899 getOutputCharset(),
900 getStylesheets());
901 output.beginBody(CssClass.BODY_CONTENT_PACKAGE_TREE);
902 printNavBarTop(output, "package-tree");
904 output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for Package " + packageDoc.name());
906 ClassDoc[] classDocs = packageDoc.allClasses();
907 printClassTree(output, classDocs);
908 printInterfaceTree(output, classDocs);
910 printNavBarBottom(output, "package-tree");
911 output.endBody();
912 output.endPage();
913 output.close();
916 private void printFullTreePage()
917 throws IOException
919 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
920 "tree" + filenameExtension),
921 ".");
922 output.beginPage(getPageTitle("Hierarchy"),
923 getOutputCharset(),
924 getStylesheets());
925 output.beginBody(CssClass.BODY_CONTENT_FULL_TREE);
926 printNavBarTop(output, "full-tree");
928 output.div(CssClass.PACKAGE_TREE_TITLE, "Hierarchy for All Packages");
930 output.beginDiv(CssClass.FULL_TREE_PACKAGELIST);
931 output.div(CssClass.FULL_TREE_PACKAGELIST_HEADER, "Package Hierarchies:");
932 output.beginDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
933 Set allPackages = getAllPackages();
934 Iterator it = allPackages.iterator();
935 while (it.hasNext()) {
936 PackageDoc packageDoc = (PackageDoc)it.next();
937 output.beginAnchor(getPackageURL(packageDoc) + "tree" + filenameExtension);
938 output.print(packageDoc.name());
939 output.endAnchor();
940 if (it.hasNext()) {
941 output.print(", ");
944 output.endDiv(CssClass.FULL_TREE_PACKAGELIST_ITEM);
945 output.endDiv(CssClass.FULL_TREE_PACKAGELIST);
947 ClassDoc[] classDocs = getRootDoc().classes();
948 printClassTree(output, classDocs);
949 printInterfaceTree(output, classDocs);
951 printNavBarBottom(output, "full-tree");
952 output.endBody();
953 output.endPage();
954 output.close();
957 private void printIndexEntry(HtmlPage output, Doc entry)
959 output.beginDiv(CssClass.INDEX_ENTRY);
960 output.beginDiv(CssClass.INDEX_ENTRY_KEY);
961 String anchor = null;
962 String description = null;
963 if (entry instanceof PackageDoc) {
964 output.beginAnchor(getPackageURL((PackageDoc)entry) + "package-summary" + filenameExtension);
965 output.print(entry.name());
966 output.endAnchor();
967 output.print(" - package");
969 else if (entry instanceof ClassDoc) {
970 ClassDoc classDoc = (ClassDoc)entry;
971 output.beginAnchor(getClassURL(classDoc));
972 output.print(entry.name() + getTypeParameters(classDoc));
973 output.endAnchor();
974 output.print(" - ");
975 if (entry.isInterface()) {
976 output.print("interface ");
978 else if (entry.isException()) {
979 output.print("exception ");
981 else if (entry.isError()) {
982 output.print("error ");
984 else {
985 output.print("class ");
987 String packageName = classDoc.containingPackage().name();
988 if (packageName.length() > 0) {
989 output.print(packageName);
990 output.print(".");
992 printType(output, classDoc);
994 else {
995 ProgramElementDoc memberDoc = (ProgramElementDoc)entry;
996 output.beginAnchor(getMemberDocURL(output, memberDoc));
997 output.print(entry.name());
998 if (memberDoc instanceof ExecutableMemberDoc) {
999 output.print(((ExecutableMemberDoc)memberDoc).signature());
1001 output.endAnchor();
1002 output.print(" - ");
1004 if (memberDoc.isStatic()) {
1005 output.print("static ");
1008 if (entry.isConstructor()) {
1009 output.print("constructor for class ");
1011 else if (entry.isMethod()) {
1012 output.print("method in class ");
1014 else if (entry.isField()) {
1015 output.print("field in class ");
1017 ClassDoc containingClass = memberDoc.containingClass();
1018 String packageName = containingClass.containingPackage().name();
1019 if (packageName.length() > 0) {
1020 output.print(packageName);
1021 output.print(".");
1023 printType(output, containingClass);
1025 output.endDiv(CssClass.INDEX_ENTRY_KEY);
1026 output.beginDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
1027 printTags(output, entry, entry.firstSentenceTags(), true);
1028 output.endDiv(CssClass.INDEX_ENTRY_DESCRIPTION);
1029 output.endDiv(CssClass.INDEX_ENTRY);
1032 private void printFrameSetPage()
1033 throws IOException
1035 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1036 "index" + filenameExtension),
1037 ".",
1038 HtmlPage.DOCTYPE_FRAMESET);
1040 String title = getWindowTitle();
1041 output.beginPage(title, getOutputCharset(), getStylesheets());
1042 output.beginElement("frameset", "cols", "20%,80%");
1044 String contentURL;
1045 if (isSinglePackage()) {
1046 output.atomicElement("frame",
1047 new String[] { "src", "name" },
1048 new String[] { getPackageURL(getSinglePackage()) + "classes" + filenameExtension, "classes" });
1049 contentURL = getPackageURL(getSinglePackage()) + "package-summary.html";
1051 else {
1052 output.beginElement("frameset", "rows", "25%,75%");
1053 output.atomicElement("frame",
1054 new String[] { "src", "name" },
1055 new String[] { "all-packages" + filenameExtension, "packages" });
1056 output.atomicElement("frame",
1057 new String[] { "src", "name" },
1058 new String[] { "all-classes" + filenameExtension, "classes" });
1059 output.endElement("frameset");
1060 contentURL = "overview-summary" + filenameExtension;
1062 output.atomicElement("frame",
1063 new String[] { "src", "name" },
1064 new String[] { contentURL, "content" });
1065 output.endElement("frameset");
1066 output.endPage();
1067 output.close();
1070 private void printPackagesMenuPage()
1071 throws IOException
1073 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1074 "all-packages" + filenameExtension),
1075 ".");
1076 output.beginPage(getPageTitle("Package Menu"), getOutputCharset(), getStylesheets());
1077 output.beginBody(CssClass.BODY_MENU_PACKAGES, false);
1079 output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
1080 output.beginAnchor("all-classes" + filenameExtension,
1081 null,
1082 "classes");
1083 output.print("All Classes");
1084 output.endAnchor();
1085 output.endSpan(CssClass.PACKAGE_MENU_ENTRY);
1087 output.div(CssClass.PACKAGE_MENU_TITLE, "Packages");
1089 output.beginDiv(CssClass.PACKAGE_MENU_LIST);
1091 Set packageDocs = getAllPackages();
1092 Iterator it = packageDocs.iterator();
1093 while (it.hasNext()) {
1094 PackageDoc packageDoc = (PackageDoc)it.next();
1095 output.beginSpan(CssClass.PACKAGE_MENU_ENTRY);
1096 output.beginAnchor(getPackageURL(packageDoc) + "classes" + filenameExtension,
1097 null,
1098 "classes");
1099 if (packageDoc.name().length() > 0) {
1100 output.print(packageDoc.name());
1102 else {
1103 output.print("&lt;unnamed package&gt;");
1105 output.endAnchor();
1106 output.endSpan(CssClass.PACKAGE_MENU_ENTRY);
1107 output.br();
1110 output.endDiv(CssClass.PACKAGE_MENU_LIST);
1111 output.endBody();
1112 output.endPage();
1113 output.close();
1116 private void printClassMenuEntry(HtmlPage output, ClassDoc classDoc)
1118 CssClass entryClass;
1119 if (classDoc.isInterface()) {
1120 entryClass = CssClass.CLASS_MENU_ENTRY_INTERFACE;
1122 else {
1123 entryClass = CssClass.CLASS_MENU_ENTRY_CLASS;
1125 output.beginSpan(entryClass);
1126 output.beginAnchor(getClassDocURL(output, classDoc),
1127 classDoc.qualifiedTypeName(),
1128 "content");
1129 output.print(classDoc.name());
1130 output.endAnchor();
1131 output.endSpan(entryClass);
1132 output.br();
1135 private void printClassMenuSection(HtmlPage output, Collection classDocs, String header)
1137 if (!classDocs.isEmpty()) {
1138 output.div(CssClass.CLASS_MENU_SUBTITLE, header);
1139 Iterator it = classDocs.iterator();
1140 while (it.hasNext()) {
1141 ClassDoc classDoc = (ClassDoc)it.next();
1142 printClassMenuEntry(output, classDoc);
1147 private void printClassMenuList(HtmlPage output, ClassDoc[] classDocs, boolean categorized)
1149 output.beginDiv(CssClass.CLASS_MENU_LIST);
1151 if (categorized) {
1152 Set classes = new TreeSet();
1153 Set interfaces = new TreeSet();
1154 Set exceptions = new TreeSet();
1155 Set errors = new TreeSet();
1157 for (int i=0; i<classDocs.length; ++i) {
1158 ClassDoc classDoc = classDocs[i];
1159 if (classDoc.isInterface()) {
1160 interfaces.add(classDoc);
1162 else if (classDoc.isException()) {
1163 exceptions.add(classDoc);
1165 else if (classDoc.isError()) {
1166 errors.add(classDoc);
1168 else {
1169 classes.add(classDoc);
1172 printClassMenuSection(output, interfaces, "Interfaces");
1173 printClassMenuSection(output, classes, "Classes");
1174 printClassMenuSection(output, exceptions, "Exceptions");
1175 printClassMenuSection(output, errors, "Errors");
1177 else {
1178 for (int i=0; i<classDocs.length; ++i) {
1179 ClassDoc classDoc = classDocs[i];
1180 if (classDoc.isIncluded()) {
1181 printClassMenuEntry(output, classDoc);
1186 output.endDiv(CssClass.CLASS_MENU_LIST);
1189 private void printAllClassesMenuPage()
1190 throws IOException
1192 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1193 "all-classes" + filenameExtension),
1194 ".");
1195 output.beginPage(getPageTitle("Class Menu"), getOutputCharset(), getStylesheets());
1196 output.beginBody(CssClass.BODY_MENU_CLASSES, false);
1198 output.div(CssClass.CLASS_MENU_TITLE, "All Classes");
1200 printClassMenuList(output, getRootDoc().classes(), false);
1202 output.endBody();
1203 output.endPage();
1204 output.close();
1207 private void printPackageClassesMenuPage(File packageDir, String pathToRoot, PackageDoc packageDoc)
1208 throws IOException
1210 HtmlPage output = newHtmlPage(new File(packageDir,
1211 "classes" + filenameExtension),
1212 pathToRoot);
1214 output.beginPage(getPageTitle(packageDoc.name() + " Class Menu"),
1215 getOutputCharset(), getStylesheets());
1216 output.beginBody(CssClass.BODY_MENU_CLASSES, false);
1218 output.beginDiv(CssClass.CLASS_MENU_TITLE);
1219 output.beginAnchor("package-summary" + filenameExtension, "", "content");
1220 if (packageDoc.name().length() > 0) {
1221 output.print(packageDoc.name());
1223 else {
1224 output.print("&lt;Unnamed&gt;");
1226 output.endAnchor();
1227 output.endDiv(CssClass.CLASS_MENU_TITLE);
1229 printClassMenuList(output, packageDoc.allClasses(), true);
1231 output.endBody();
1232 output.endPage();
1233 output.close();
1236 private void printSplitIndex()
1237 throws IOException
1239 Map categorizedIndex = getCategorizedIndex();
1240 Iterator it = categorizedIndex.keySet().iterator();
1241 int n = 1;
1242 int count = categorizedIndex.size();
1243 while (it.hasNext()) {
1244 Character c = (Character)it.next();
1245 List classList = (List)categorizedIndex.get(c);
1246 printIndexPage(n++, count, c, classList);
1250 private void printIndexPage()
1251 throws IOException
1253 printIndexPage(0, 0, null, null);
1256 private void printIndexPage(int index, int maxIndex, Character letter, List classList)
1257 throws IOException
1259 String pageName = "alphaindex";
1260 if (null != letter) {
1261 pageName += "-" + index;
1263 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1264 pageName + filenameExtension),
1265 ".");
1266 output.beginPage(getPageTitle("Alphabetical Index"),
1267 getOutputCharset(),
1268 getStylesheets());
1269 output.beginBody(CssClass.BODY_CONTENT_INDEX);
1270 if (null == letter) {
1271 printNavBarTop(output, "index");
1273 else {
1274 printNavBarTop(output, "split-index", null,
1275 (index > 1) ? new Integer(index - 1) : null,
1276 (index < maxIndex) ? new Integer(index + 1) : null);
1280 String title;
1281 if (null == letter) {
1282 title = "Alphabetical Index";
1284 else {
1285 title = "Alphabetical Index: " + letter;
1287 output.div(CssClass.INDEX_TITLE, title);
1289 if (null != letter || getCategorizedIndex().keySet().size() > 1) {
1290 output.beginDiv(CssClass.INDEX_LETTERS);
1292 Iterator it = getCategorizedIndex().keySet().iterator();
1293 int n = 1;
1294 while (it.hasNext()) {
1295 Character c = (Character)it.next();
1296 output.beginSpan(CssClass.INDEX_LETTER);
1297 if (letter != null) {
1298 output.beginAnchor("alphaindex-" + n + filenameExtension);
1300 else {
1301 output.beginAnchor("#" + c);
1303 output.print(c.toString());
1304 output.endAnchor();
1305 output.endSpan(CssClass.INDEX_LETTER);
1306 output.beginSpan(CssClass.INDEX_LETTER_SPACER);
1307 output.print(" ");
1308 output.endSpan(CssClass.INDEX_LETTER_SPACER);
1309 ++n;
1313 output.endDiv(CssClass.INDEX_LETTERS);
1316 if (null != letter) {
1317 printIndexCategory(output, letter, classList);
1319 else {
1320 Map categorizedIndex = getCategorizedIndex();
1321 Iterator categoryIt = categorizedIndex.keySet().iterator();
1323 while (categoryIt.hasNext()) {
1324 letter = (Character)categoryIt.next();
1325 classList = (List)categorizedIndex.get(letter);
1326 output.anchorName(letter.toString());
1327 printIndexCategory(output, letter, classList);
1331 printNavBarBottom(output, "index");
1332 output.endBody();
1333 output.endPage();
1334 output.close();
1337 private void printIndexCategory(HtmlPage output, Character letter, List classList)
1339 Iterator it = classList.iterator();
1341 output.div(CssClass.INDEX_CATEGORY_HEADER, letter.toString());
1342 output.beginDiv(CssClass.INDEX_CATEGORY);
1343 while (it.hasNext()) {
1344 Doc entry = (Doc)it.next();
1345 printIndexEntry(output, entry);
1347 output.endDiv(CssClass.INDEX_CATEGORY);
1350 private void printDeprecationSummary(HtmlPage output, List docs, String header)
1352 if (!docs.isEmpty()) {
1353 output.beginDiv(CssClass.TABLE_CONTAINER);
1354 output.beginTable(CssClass.DEPRECATION_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1355 output.rowDiv(CssClass.TABLE_HEADER, header);
1357 Iterator it = docs.iterator();
1358 while (it.hasNext()) {
1359 Doc doc = (Doc)it.next();
1360 output.beginRow();
1362 output.beginCell(CssClass.DEPRECATION_SUMMARY_LEFT);
1363 if (doc instanceof Type) {
1364 printType(output, (Type)doc);
1366 else {
1367 ProgramElementDoc memberDoc = (ProgramElementDoc)doc;
1368 output.beginAnchor(getMemberDocURL(output, memberDoc));
1369 output.print(memberDoc.containingClass().qualifiedName());
1370 output.print(".");
1371 output.print(memberDoc.name());
1372 if (memberDoc instanceof ExecutableMemberDoc) {
1373 output.print(((ExecutableMemberDoc)memberDoc).flatSignature());
1375 output.endAnchor();
1377 output.beginDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);
1378 printTags(output, doc, doc.tags("deprecated")[0].firstSentenceTags(), true);
1379 output.endDiv(CssClass.DEPRECATION_SUMMARY_DESCRIPTION);
1381 output.endCell();
1383 output.endRow();
1385 output.endTable();
1386 output.endDiv(CssClass.TABLE_CONTAINER);
1387 output.print("\n");
1392 private void printSerializationPage()
1393 throws IOException
1395 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1396 "serialized-form" + filenameExtension),
1397 ".");
1398 output.beginPage(getPageTitle("Serialized Form"),
1399 getOutputCharset(),
1400 getStylesheets());
1401 output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
1402 printNavBarTop(output, "serialized");
1404 output.div(CssClass.SERIALIZED_TITLE, "Serialized Form");
1406 Iterator it = getAllPackages().iterator();
1408 while (it.hasNext()) {
1410 PackageDoc packageDoc = (PackageDoc)it.next();
1412 List serializableClasses = new LinkedList();
1413 ClassDoc[] classes = packageDoc.allClasses();
1414 for (int i=0; i<classes.length; ++i) {
1415 ClassDoc classDoc = classes[i];
1416 if (classDoc.isSerializable() || classDoc.isExternalizable()) {
1417 serializableClasses.add(classDoc);
1421 if (!serializableClasses.isEmpty()) {
1422 output.div(CssClass.SERIALIZED_PACKAGE_HEADER, "Package " + packageDoc.name());
1424 Iterator cit = serializableClasses.iterator();
1425 while (cit.hasNext()) {
1426 ClassDoc classDoc = (ClassDoc)cit.next();
1428 output.anchorName(classDoc.qualifiedTypeName());
1430 output.beginDiv(CssClass.SERIALIZED_CLASS_HEADER);
1431 output.print("Class ");
1432 printType(output, classDoc, true);
1433 output.print(" extends ");
1434 printType(output, classDoc.superclass());
1435 output.print(" implements Serializable");
1436 output.endDiv(CssClass.SERIALIZED_CLASS_HEADER);
1438 FieldDoc serialVersionUidField = findField(classDoc, "serialVersionUID");
1439 if (null != serialVersionUidField
1440 && serialVersionUidField.isFinal()
1441 && serialVersionUidField.isStatic()
1442 && serialVersionUidField.type().typeName().equals("long")) {
1444 String fieldValue = serialVersionUidField.constantValueExpression();
1445 if (null != fieldValue) {
1446 output.beginDiv(CssClass.SERIALIZED_SVUID_OUTER);
1447 output.span(CssClass.SERIALIZED_SVUID_HEADER, "serialVersionUID: ");
1448 output.span(CssClass.SERIALIZED_SVUID_VALUE, fieldValue);
1449 output.endDiv(CssClass.SERIALIZED_SVUID_OUTER);
1452 printMemberDetails(output,
1453 classDoc.serializationMethods(),
1454 "Serialization Methods",
1455 true, null);
1456 printMemberDetails(output,
1457 classDoc.serializableFields(),
1458 "Serialized Fields",
1459 true, null);
1464 printNavBarBottom(output, "serialized");
1466 output.endBody();
1467 output.endPage();
1468 output.close();
1472 private void printDeprecationPage()
1473 throws IOException
1475 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1476 "deprecated" + filenameExtension),
1477 ".");
1478 output.beginPage(getPageTitle("Deprecated API"),
1479 getOutputCharset(),
1480 getStylesheets());
1481 output.beginBody(CssClass.BODY_CONTENT_DEPRECATED);
1482 printNavBarTop(output, "deprecated");
1484 output.div(CssClass.DEPRECATION_TITLE, "Deprecated API");
1486 List deprecatedInterfaces = new LinkedList();
1487 List deprecatedExceptions = new LinkedList();
1488 List deprecatedErrors = new LinkedList();
1489 List deprecatedClasses = new LinkedList();
1490 List deprecatedFields = new LinkedList();
1491 List deprecatedMethods = new LinkedList();
1492 List deprecatedConstructors = new LinkedList();
1494 ClassDoc[] classDocs = getRootDoc().classes();
1495 for (int i=0; i<classDocs.length; ++i) {
1496 ClassDoc classDoc = classDocs[i];
1498 Tag[] deprecatedTags = classDoc.tags("deprecated");
1499 if (null != deprecatedTags && deprecatedTags.length > 0) {
1500 if (classDoc.isInterface()) {
1501 deprecatedInterfaces.add(classDoc);
1503 else if (classDoc.isException()) {
1504 deprecatedExceptions.add(classDoc);
1506 else if (classDoc.isError()) {
1507 deprecatedErrors.add(classDoc);
1509 else {
1510 deprecatedClasses.add(classDoc);
1514 ConstructorDoc[] constructors = classDoc.constructors();
1515 for (int j=0; j<constructors.length; ++j) {
1516 Tag[] deprecatedTags = constructors[j].tags("deprecated");
1517 if (null != deprecatedTags && deprecatedTags.length > 0) {
1518 deprecatedConstructors.add(constructors[j]);
1521 MethodDoc[] methods = classDoc.methods();
1522 for (int j=0; j<methods.length; ++j) {
1523 Tag[] deprecatedTags = methods[j].tags("deprecated");
1524 if (null != deprecatedTags && deprecatedTags.length > 0) {
1525 deprecatedMethods.add(methods[j]);
1528 FieldDoc[] fields = classDoc.fields();
1529 for (int j=0; j<fields.length; ++j) {
1530 Tag[] deprecatedTags = fields[j].tags("deprecated");
1531 if (null != deprecatedTags && deprecatedTags.length > 0) {
1532 deprecatedFields.add(fields[j]);
1537 if (!deprecatedInterfaces.isEmpty()
1538 || !deprecatedClasses.isEmpty()
1539 || !deprecatedExceptions.isEmpty()
1540 || !deprecatedErrors.isEmpty()
1541 || !deprecatedFields.isEmpty()
1542 || !deprecatedMethods.isEmpty()
1543 || !deprecatedConstructors.isEmpty()) {
1545 output.beginDiv(CssClass.DEPRECATION_TOC);
1546 output.div(CssClass.DEPRECATION_TOC_HEADER, "Contents");
1547 output.beginDiv(CssClass.DEPRECATION_TOC_LIST);
1548 if (!deprecatedInterfaces.isEmpty()) {
1549 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1550 output.anchor("#interfaces", "Deprecated Interfaces");
1551 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1553 if (!deprecatedClasses.isEmpty()) {
1554 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1555 output.anchor("#classes", "Deprecated Classes");
1556 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1558 if (!deprecatedExceptions.isEmpty()) {
1559 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1560 output.anchor("#exceptions", "Deprecated Exceptions");
1561 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1563 if (!deprecatedErrors.isEmpty()) {
1564 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1565 output.anchor("#errors", "Deprecated Errors");
1566 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1568 if (!deprecatedFields.isEmpty()) {
1569 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1570 output.anchor("#fields", "Deprecated Fields");
1571 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1573 if (!deprecatedMethods.isEmpty()) {
1574 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1575 output.anchor("#methods", "Deprecated Methods");
1576 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1578 if (!deprecatedConstructors.isEmpty()) {
1579 output.beginDiv(CssClass.DEPRECATION_TOC_ENTRY);
1580 output.anchor("#constructors", "Deprecated Constructors");
1581 output.endDiv(CssClass.DEPRECATION_TOC_ENTRY);
1583 output.endDiv(CssClass.DEPRECATION_TOC_LIST);
1584 output.endDiv(CssClass.DEPRECATION_TOC);
1585 output.beginDiv(CssClass.DEPRECATION_LIST);
1587 output.anchorName("interfaces");
1588 printDeprecationSummary(output, deprecatedInterfaces, "Deprecated Interfaces");
1590 output.anchorName("classes");
1591 printDeprecationSummary(output, deprecatedClasses, "Deprecated Classes");
1593 output.anchorName("exceptions");
1594 printDeprecationSummary(output, deprecatedExceptions, "Deprecated Exceptions");
1596 output.anchorName("errors");
1597 printDeprecationSummary(output, deprecatedErrors, "Deprecated Errors");
1599 output.anchorName("fields");
1600 printDeprecationSummary(output, deprecatedFields, "Deprecated Fields");
1602 output.anchorName("methods");
1603 printDeprecationSummary(output, deprecatedMethods, "Deprecated Methods");
1605 output.anchorName("constructors");
1606 printDeprecationSummary(output, deprecatedConstructors, "Deprecated Constructors");
1608 output.endDiv(CssClass.DEPRECATION_LIST);
1610 else {
1611 output.beginDiv(CssClass.DEPRECATION_EMPTY);
1612 output.print("No deprecated classes or class members in this API.");
1613 output.endDiv(CssClass.DEPRECATION_EMPTY);
1617 printNavBarBottom(output, "deprecated");
1618 output.endBody();
1619 output.endPage();
1620 output.close();
1623 private void printAboutPage()
1624 throws IOException
1626 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1627 "about" + filenameExtension),
1628 ".");
1629 output.beginPage(getPageTitle("About"),
1630 getOutputCharset(),
1631 getStylesheets());
1632 output.beginBody(CssClass.BODY_CONTENT_ABOUT);
1634 printNavBarTop(output, "about");
1636 output.div(CssClass.ABOUT_TITLE, "About");
1638 output.beginDiv(CssClass.ABOUT_GENERATOR);
1639 output.print("Generated by ");
1640 output.print("Gjdoc");
1641 output.print(" HtmlDoclet ");
1642 output.print(getDocletVersion());
1643 output.print(", part of ");
1644 output.beginAnchor("http://www.gnu.org/software/classpath/cp-tools/", "", "_top");
1645 output.print("GNU Classpath Tools");
1646 output.endAnchor();
1647 output.print(", on ");
1648 DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG,
1649 DateFormat.LONG,
1650 Locale.US);
1651 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
1652 Locale.US);
1653 format.setCalendar(cal);
1654 output.print(format.format(new Date()));
1655 output.print(".");
1656 output.endDiv(CssClass.ABOUT_GENERATOR);
1658 printNavBarBottom(output, "about");
1660 output.endBody();
1661 output.endPage();
1662 output.close();
1665 private void printSourcePage(File packageDir, ClassDoc classDoc, String sourceXhtml)
1666 throws IOException
1668 HtmlPage output = newHtmlPage(new File(packageDir,
1669 classDoc.name() + "-source" + filenameExtension),
1670 getPathToRoot(packageDir, getTargetDirectory()));
1671 output.beginPage(getPageTitle("Source for " + classDoc.qualifiedTypeName()),
1672 getOutputCharset(),
1673 getStylesheets());
1675 output.beginBody(CssClass.BODY_CONTENT_SOURCE);
1677 printNavBarTop(output, "source", classDoc, null, null);
1679 output.div(CssClass.SOURCE_TITLE, "Source for " + classDoc.qualifiedTypeName());
1680 output.beginDiv(CssClass.SOURCE);
1681 output.print(sourceXhtml);
1682 output.endDiv(CssClass.SOURCE);
1684 printNavBarBottom(output, "source", classDoc);
1686 output.endBody();
1687 output.endPage();
1689 output.close();
1692 private void printHelpPage()
1693 throws IOException
1695 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1696 "help" + filenameExtension),
1697 ".");
1698 output.beginPage(getPageTitle("Help"),
1699 getOutputCharset(),
1700 getStylesheets());
1701 output.beginBody(CssClass.BODY_CONTENT_HELP);
1703 printNavBarTop(output, "help");
1705 InputStream helpIn;
1706 if (null != optionHelpFile.getValue()){
1707 helpIn = new FileInputStream(optionHelpFile.getValue());
1709 else {
1710 helpIn = getClass().getResourceAsStream("/htmldoclet/help.xhtml");
1712 output.insert(new InputStreamReader(helpIn, "utf-8"));
1713 helpIn.close();
1715 printNavBarBottom(output, "help");
1717 output.endBody();
1718 output.endPage();
1719 output.close();
1722 private void printOverviewPage()
1723 throws IOException
1725 HtmlPage output = newHtmlPage(new File(getTargetDirectory(),
1726 "overview-summary" + filenameExtension),
1727 ".");
1728 output.beginPage(getWindowTitle(),
1729 getOutputCharset(),
1730 getStylesheets());
1731 output.beginBody(CssClass.BODY_CONTENT_OVERVIEW);
1733 printNavBarTop(output, "overview");
1735 String overviewHeader;
1736 if (null != optionDocTitle.getValue()) {
1737 overviewHeader = optionDocTitle.getValue();
1739 else if (null != optionTitle.getValue()) {
1740 overviewHeader = optionTitle.getValue();
1742 else {
1743 overviewHeader = null;
1746 if (null != overviewHeader) {
1747 output.div(CssClass.OVERVIEW_TITLE, overviewHeader);
1750 output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);
1751 printTags(output, getRootDoc(), getRootDoc().firstSentenceTags(), true);
1752 output.endDiv(CssClass.OVERVIEW_DESCRIPTION_TOP);
1754 List packageGroups = getPackageGroups();
1756 if (packageGroups.isEmpty()) {
1758 printOverviewPackages(output, getAllPackages(),
1759 "All Packages");
1761 else {
1762 Set otherPackages = new LinkedHashSet();
1763 otherPackages.addAll(getAllPackages());
1765 Iterator it = packageGroups.iterator();
1766 while (it.hasNext()) {
1767 PackageGroup packageGroup = (PackageGroup)it.next();
1768 printOverviewPackages(output,
1769 packageGroup.getPackages(),
1770 packageGroup.getName());
1771 otherPackages.removeAll(packageGroup.getPackages());
1774 if (!otherPackages.isEmpty()) {
1775 printOverviewPackages(output,
1776 otherPackages,
1777 "Other Packages");
1781 output.anchorName("description");
1782 output.beginDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);
1783 printTags(output, getRootDoc(), getRootDoc().inlineTags(), false);
1784 output.endDiv(CssClass.OVERVIEW_DESCRIPTION_FULL);
1786 printNavBarBottom(output, "overview");
1787 output.endBody();
1788 output.endPage();
1789 output.close();
1792 private void printOverviewPackages(HtmlPage output, Collection packageDocs, String header)
1794 output.beginDiv(CssClass.TABLE_CONTAINER);
1795 output.beginTable(CssClass.OVERVIEW_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1796 output.rowDiv(CssClass.TABLE_HEADER, header);
1798 Iterator it = packageDocs.iterator();
1799 while (it.hasNext()) {
1800 PackageDoc packageDoc = (PackageDoc)it.next();
1801 output.beginRow();
1803 output.beginCell(CssClass.OVERVIEW_SUMMARY_LEFT);
1804 output.beginAnchor(getPackageURL(packageDoc) + "package-summary" + filenameExtension);
1805 output.print(packageDoc.name());
1806 output.endAnchor();
1807 output.endCell();
1809 output.beginCell(CssClass.OVERVIEW_SUMMARY_RIGHT);
1810 printTags(output, packageDoc, packageDoc.firstSentenceTags(), true);
1811 output.endCell();
1812 output.endRow();
1814 output.endTable();
1815 output.endDiv(CssClass.TABLE_CONTAINER);
1818 private void printClassUsagePage(File packageDir, String pathToRoot, ClassDoc classDoc)
1819 throws IOException
1821 HtmlPage output = newHtmlPage(new File(packageDir,
1822 classDoc.name() + "-uses" + filenameExtension),
1823 pathToRoot);
1824 output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(), getStylesheets());
1825 output.beginBody(CssClass.BODY_CONTENT_USES);
1826 printNavBarTop(output, "uses", classDoc, null, null);
1828 output.div(CssClass.USAGE_TITLE,
1829 "Uses of " + getClassTypeName(classDoc)
1830 + " " + classDoc.qualifiedName());
1832 Map packageToUsageTypeMap = getUsageOfClass(classDoc);
1833 if (null != packageToUsageTypeMap && !packageToUsageTypeMap.isEmpty()) {
1835 Iterator packagesIterator = packageToUsageTypeMap.keySet().iterator();
1836 while (packagesIterator.hasNext()) {
1837 PackageDoc packageDoc = (PackageDoc)packagesIterator.next();
1839 output.div(CssClass.USAGE_PACKAGE_TITLE, "Uses in package " + packageDoc.name());
1841 Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(packageDoc);
1842 Iterator usageTypeIterator = usageTypeToUsersMap.keySet().iterator();
1843 while (usageTypeIterator.hasNext()) {
1844 UsageType usageType = (UsageType)usageTypeIterator.next();
1846 output.beginTable(CssClass.USAGE_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
1847 output.rowDiv(CssClass.USAGE_TABLE_HEADER, format("usagetype." + usageType.getId(),
1848 classDoc.qualifiedName()));
1850 Set users = (Set)usageTypeToUsersMap.get(usageType);
1851 Iterator userIterator = users.iterator();
1852 while (userIterator.hasNext()) {
1853 Doc user = (Doc)userIterator.next();
1855 output.beginRow();
1857 if (user instanceof ClassDoc) {
1858 output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1859 output.print("class");
1860 output.endCell();
1862 output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1863 output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1864 printType(output, ((ClassDoc)user));
1865 output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1866 output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1867 printTags(output, ((ClassDoc)user), ((ClassDoc)user).firstSentenceTags(), true);
1868 output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1869 output.endCell();
1871 else if (user instanceof FieldDoc) {
1872 FieldDoc fieldDoc = (FieldDoc)user;
1874 output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1875 printType(output, ((FieldDoc)user).type());
1876 output.endCell();
1878 output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1879 output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1880 printType(output, ((FieldDoc)user).containingClass());
1881 output.print(".");
1882 output.beginAnchor(getMemberDocURL(output, (FieldDoc)user));
1883 output.print(((FieldDoc)user).name());
1884 output.endAnchor();
1885 output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1886 output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1887 printTags(output, ((FieldDoc)user), ((FieldDoc)user).firstSentenceTags(), true);
1888 output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1889 output.endCell();
1891 else if (user instanceof MethodDoc) {
1892 MethodDoc methodDoc = (MethodDoc)user;
1894 output.beginCell(CssClass.USAGE_SUMMARY_LEFT);
1895 printType(output, ((MethodDoc)user).returnType());
1896 output.endCell();
1898 output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1899 output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1900 printType(output, ((MethodDoc)user).containingClass());
1901 output.print(".");
1902 output.beginAnchor(getMemberDocURL(output, (MethodDoc)user));
1903 output.print(((MethodDoc)user).name());
1904 output.endAnchor();
1905 printParameters(output, (ExecutableMemberDoc)user);
1906 output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1907 output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1908 printTags(output, ((MethodDoc)user), ((MethodDoc)user).firstSentenceTags(), true);
1909 output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1910 output.endCell();
1912 else if (user instanceof ConstructorDoc) {
1913 ConstructorDoc constructorDoc = (ConstructorDoc)user;
1915 output.beginCell(CssClass.USAGE_SUMMARY_RIGHT);
1916 output.beginDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1917 printType(output, ((ConstructorDoc)user).containingClass());
1918 output.print(".");
1919 output.beginAnchor(getMemberDocURL(output, (ConstructorDoc)user));
1920 output.print(((ConstructorDoc)user).name());
1921 output.endAnchor();
1922 printParameters(output, (ExecutableMemberDoc)user);
1923 output.endDiv(CssClass.USAGE_SUMMARY_SYNOPSIS);
1924 output.beginDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1925 printTags(output, ((ConstructorDoc)user),
1926 ((ConstructorDoc)user).firstSentenceTags(), true);
1927 output.endDiv(CssClass.USAGE_SUMMARY_DESCRIPTION);
1928 output.endCell();
1931 output.endRow();
1933 output.endTable();
1937 else {
1938 output.div(CssClass.USAGE_EMPTY,
1939 getClassTypeName(classDoc)
1940 + " " + classDoc.qualifiedName() + " is not used by any class in this documentation set.");
1942 printNavBarBottom(output, "uses", classDoc);
1943 output.endBody();
1944 output.endPage();
1945 output.close();
1948 private void printSuperTreeRec(HtmlPage output, ListIterator it, int level)
1950 if (it.hasPrevious()) {
1951 ClassDoc cd = (ClassDoc)it.previous();
1952 output.beginElement("li", new String[] { "class" }, new String[] { "inheritance " + level });
1953 output.beginElement("code");
1954 if (it.hasPrevious()) {
1955 printType(output, cd, true);
1957 else {
1958 output.print(cd.qualifiedName() + getTypeParameters(cd));
1960 output.endElement("code");
1961 output.endElement("li");
1963 output.beginElement("li");
1965 if (it.hasPrevious()) {
1966 output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance " + (level + 1) });
1967 printSuperTreeRec(output, it, level + 1);
1968 output.endElement("ul");
1971 output.endElement("li");
1975 private static boolean isSubInterface(ClassDoc classDoc, ClassDoc otherClassDoc)
1977 ClassDoc[] interfaces = otherClassDoc.interfaces();
1978 for (int i=0; i<interfaces.length; ++i) {
1979 if (classDoc == interfaces[i]) {
1980 return true;
1982 else if (isSubInterface(classDoc, interfaces[i])) {
1983 return true;
1986 return false;
1989 private void printCommaSeparatedTypes(HtmlPage output,
1990 Collection list,
1991 String header,
1992 CssClass cssClass)
1994 if (!list.isEmpty()) {
1995 output.beginDiv(cssClass);
1996 output.div(CssClass.CLASS_KNOWNIMPLEMENTING_HEADER, header);
1997 output.beginDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
1998 Iterator it = list.iterator();
1999 while (it.hasNext()) {
2000 Type type = (Type)it.next();
2001 printType(output, type);
2002 if (it.hasNext()) {
2003 output.print(", ");
2006 output.endDiv(CssClass.CLASS_KNOWNIMPLEMENTING_ITEM);
2007 output.endDiv(cssClass);
2011 private void printClassPage(File packageDir, String pathToRoot,
2012 ClassDoc classDoc, ClassDoc prevClassDoc, ClassDoc nextClassDoc)
2013 throws IOException
2015 HtmlPage output = newHtmlPage(new File(packageDir,
2016 classDoc.name() + filenameExtension),
2017 pathToRoot);
2018 Set keywords = new LinkedHashSet();
2020 keywords.add(classDoc.qualifiedName() + " class");
2021 FieldDoc[] fieldDocs = classDoc.fields();
2022 for (int i=0; i<fieldDocs.length; ++i) {
2023 FieldDoc fieldDoc = fieldDocs[i];
2024 keywords.add(fieldDoc.name());
2027 MethodDoc[] methodDocs = classDoc.methods();
2028 for (int i=0; i<methodDocs.length; ++i) {
2029 MethodDoc methodDoc = methodDocs[i];
2030 keywords.add(methodDoc.name() + "()");
2033 String parameters = getTypeParameters(classDoc);
2035 output.beginPage(getPageTitle(classDoc.name()), getOutputCharset(),
2036 keywords, getStylesheets());
2037 output.beginBody(CssClass.BODY_CONTENT_CLASS);
2038 printNavBarTop(output, "class", classDoc, prevClassDoc, nextClassDoc);
2040 output.beginDiv(CssClass.CLASS_TITLE);
2041 output.div(CssClass.CLASS_TITLE_PACKAGE,
2042 classDoc.containingPackage().name());
2043 output.div(CssClass.CLASS_TITLE_CLASS,
2044 getClassTypeName(classDoc)
2045 + " " + classDoc.name()
2046 + parameters);
2047 output.endDiv(CssClass.CLASS_TITLE);
2049 boolean needSep = false;
2051 if (classDoc.isInterface()) {
2053 InterfaceRelation relation
2054 = (InterfaceRelation)getInterfaceRelations().get(classDoc);
2056 printCommaSeparatedTypes(output,
2057 relation.superInterfaces,
2058 "All Superinterfaces:",
2059 CssClass.CLASS_KNOWNIMPLEMENTING);
2061 printCommaSeparatedTypes(output,
2062 relation.subInterfaces,
2063 "Known Subinterfaces:",
2064 CssClass.CLASS_KNOWNIMPLEMENTING);
2066 printCommaSeparatedTypes(output,
2067 relation.implementingClasses,
2068 "Known Implementing Classes:",
2069 CssClass.CLASS_KNOWNIMPLEMENTING);
2071 needSep = !relation.superInterfaces.isEmpty()
2072 || !relation.subInterfaces.isEmpty()
2073 || !relation.implementingClasses.isEmpty();
2075 else {
2076 needSep = true;
2078 if (!"java.lang.Object".equals(classDoc.qualifiedName())) {
2079 LinkedList superClasses = new LinkedList();
2080 for (ClassDoc cd = classDoc; cd != null; cd = cd.superclass()) {
2081 superClasses.add(cd);
2083 output.beginDiv(CssClass.CLASS_INHERITANCETREE);
2084 output.beginElement("ul", new String[] { "class" }, new String[] { "inheritance 0" });
2085 printSuperTreeRec(output, superClasses.listIterator(superClasses.size()), 0);
2086 output.endElement("ul");
2087 output.endDiv(CssClass.CLASS_INHERITANCETREE);
2089 if (null != classDoc.containingClass()) {
2090 output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS);
2091 output.div(CssClass.CLASS_ENCLOSINGCLASS_HEADER, "Enclosing Class:");
2092 output.beginDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
2093 printType(output, classDoc.containingClass());
2094 output.endDiv(CssClass.CLASS_ENCLOSINGCLASS_ITEM);
2095 output.endDiv(CssClass.CLASS_ENCLOSINGCLASS);
2098 Set implementedInterfaces = getImplementedInterfaces(classDoc);
2100 printCommaSeparatedTypes(output,
2101 implementedInterfaces,
2102 "Implemented Interfaces:",
2103 CssClass.CLASS_KNOWNIMPLEMENTING);
2105 List knownDirectSubclasses = getKnownDirectSubclasses(classDoc);
2106 if (!knownDirectSubclasses.isEmpty()) {
2107 output.beginDiv(CssClass.CLASS_SUBCLASSES);
2108 output.div(CssClass.CLASS_SUBCLASSES_HEADER, "Known Direct Subclasses:");
2109 output.beginDiv(CssClass.CLASS_SUBCLASSES_ITEM);
2110 Iterator it = knownDirectSubclasses.iterator();
2111 while (it.hasNext()) {
2112 printType(output, (ClassDoc)it.next());
2113 if (it.hasNext()) {
2114 output.print(", ");
2118 output.endDiv(CssClass.CLASS_SUBCLASSES_ITEM);
2119 output.endDiv(CssClass.CLASS_SUBCLASSES_HEADER);
2120 output.endDiv(CssClass.CLASS_SUBCLASSES);
2125 if (needSep) {
2126 output.hr();
2129 output.beginDiv(CssClass.CLASS_SYNOPSIS);
2130 output.beginDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);
2131 output.print(getFullModifiers(classDoc) + ' ' + getClassTypeKeyword(classDoc)
2132 + ' ');
2133 output.beginSpan(CssClass.CLASS_SYNOPSIS_NAME);
2134 if (optionLinkSource.getValue() && null != classDoc.position()) {
2135 output.beginAnchor(getOuterClassDoc(classDoc).name() + "-source" + filenameExtension + "#line." + classDoc.position());
2136 output.print(classDoc.name() + parameters);
2137 output.endAnchor();
2139 else {
2140 output.print(classDoc.name() + parameters);
2142 output.endSpan(CssClass.CLASS_SYNOPSIS_NAME);
2143 output.endDiv(CssClass.CLASS_SYNOPSIS_DECLARATION);
2145 if (!classDoc.isInterface()) {
2146 if (null != classDoc.superclass()) {
2147 output.beginDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
2148 output.print("extends ");
2149 printType(output, classDoc.superclass());
2150 output.endDiv(CssClass.CLASS_SYNOPSIS_SUPERCLASS);
2154 ClassDoc[] interfaces = classDoc.interfaces();
2155 if (interfaces.length > 0) {
2156 output.beginDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
2157 if (!classDoc.isInterface()) {
2158 output.print("implements ");
2160 else {
2161 output.print("extends ");
2163 for (int i=0; i<interfaces.length; ++i) {
2164 if (i>0) {
2165 output.print(", ");
2167 printType(output, interfaces[i]);
2169 output.endDiv(CssClass.CLASS_SYNOPSIS_IMPLEMENTS);
2171 output.endDiv(CssClass.CLASS_SYNOPSIS);
2173 output.hr();
2175 if (!optionNoComment.getValue()) {
2176 output.beginDiv(CssClass.CLASS_DESCRIPTION);
2177 printTags(output, classDoc, classDoc.inlineTags(), false);
2178 output.endDiv(CssClass.CLASS_DESCRIPTION);
2180 printTaglets(output, classDoc.tags(), new HtmlTagletContext(classDoc, output, false));
2184 Set implementedInterfaces = getImplementedInterfaces(classDoc);
2186 boolean haveInheritedFields = false;
2187 boolean haveInheritedMethods = false;
2188 boolean haveInheritedClasses = false;
2190 if (!classDoc.isInterface()) {
2191 ClassDoc superClassDoc = classDoc.superclass();
2192 while (null != superClassDoc
2193 && (!haveInheritedFields
2194 || !haveInheritedMethods
2195 || !haveInheritedClasses)) {
2196 if (superClassDoc.fields().length > 0) {
2197 haveInheritedFields = true;
2199 if (superClassDoc.methods().length > 0) {
2200 haveInheritedMethods = true;
2202 if (superClassDoc.innerClasses().length > 0) {
2203 haveInheritedClasses = true;
2205 superClassDoc = superClassDoc.superclass();
2210 printProgramElementDocs(output, getSortedInnerClasses(classDoc),
2211 "Nested Class Summary", haveInheritedClasses,
2212 "summary-inner");
2215 ClassDoc superClassDoc = classDoc.superclass();
2216 while (null != superClassDoc) {
2217 printInheritedMembers(output, getSortedInnerClasses(superClassDoc),
2218 "Nested classes/interfaces inherited from class {0}",
2219 superClassDoc);
2220 superClassDoc = superClassDoc.superclass();
2224 printProgramElementDocs(output, getSortedFields(classDoc),
2225 "Field Summary", haveInheritedFields,
2226 "summary-fields");
2229 ClassDoc superClassDoc = classDoc.superclass();
2230 while (null != superClassDoc) {
2231 printInheritedMembers(output, getSortedFields(superClassDoc),
2232 "Fields inherited from class {0}",
2233 superClassDoc);
2234 superClassDoc = superClassDoc.superclass();
2239 Iterator it = implementedInterfaces.iterator();
2240 while (it.hasNext()) {
2241 ClassDoc implementedInterface
2242 = (ClassDoc)it.next();
2243 if (!"java.io.Serializable".equals(implementedInterface.qualifiedName())
2244 && !"java.io.Externalizable".equals(implementedInterface.qualifiedName())) {
2245 printInheritedMembers(output, getSortedFields(implementedInterface),
2246 "Fields inherited from interface {0}",
2247 implementedInterface);
2252 printProgramElementDocs(output, getSortedConstructors(classDoc),
2253 "Constructor Summary", false,
2254 "summary-constructors");
2255 printProgramElementDocs(output, getSortedMethods(classDoc),
2256 "Method Summary", haveInheritedMethods,
2257 "summary-methods");
2259 if (classDoc.isInterface()) {
2260 InterfaceRelation relation
2261 = (InterfaceRelation)getInterfaceRelations().get(classDoc);
2262 Iterator it = relation.superInterfaces.iterator();
2263 while (it.hasNext()) {
2264 ClassDoc superClassDoc = (ClassDoc)it.next();
2265 printInheritedMembers(output, getSortedMethods(superClassDoc),
2266 "Methods inherited from interface {0}",
2267 superClassDoc);
2270 else {
2271 ClassDoc superClassDoc = classDoc.superclass();
2272 while (null != superClassDoc) {
2273 printInheritedMembers(output, getSortedMethods(superClassDoc),
2274 "Methods inherited from class {0}",
2275 superClassDoc);
2276 superClassDoc = superClassDoc.superclass();
2280 printMemberDetails(output, getSortedFields(classDoc),
2281 "Field Details", false, "detail-fields");
2282 printMemberDetails(output, getSortedConstructors(classDoc),
2283 "Constructor Details", false, "detail-constructors");
2284 printMemberDetails(output, getSortedMethods(classDoc),
2285 "Method Details", false, "detail-methods");
2287 printNavBarBottom(output, "class", classDoc);
2289 output.endBody();
2290 output.endPage();
2291 output.close();
2294 private void printInheritedMembers(HtmlPage output,
2295 ProgramElementDoc[] memberDocs,
2296 String headerFormat,
2297 ClassDoc superclass)
2299 if (memberDocs.length > 0) {
2301 output.beginDiv(CssClass.TABLE_CONTAINER);
2302 output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
2303 String superclassLink;
2304 if (superclass.isIncluded()) {
2305 superclassLink = superclass.containingPackage().name()
2306 + "." + createTypeHref(output, superclass, false);
2308 else {
2309 superclassLink = createTypeHref(output, superclass, true);
2311 output.rowDiv(CssClass.TABLE_SUB_HEADER,
2312 new MessageFormat(headerFormat).format(new Object[] {
2313 superclassLink
2314 }));
2316 output.beginRow();
2317 output.beginCell(CssClass.CLASS_SUMMARY_INHERITED);
2318 for (int i=0; i<memberDocs.length; ++i) {
2319 ProgramElementDoc memberDoc = memberDocs[i];
2320 if (i > 0) {
2321 output.print(", ");
2323 String title = null;
2324 if (memberDoc.isMethod()) {
2325 title = memberDoc.name() + ((MethodDoc)memberDoc).flatSignature();
2327 else if (memberDoc.isInterface()) {
2328 title = "interface " + ((ClassDoc)memberDoc).qualifiedName();
2330 else if (memberDoc.isClass()) {
2331 title = "class " + ((ClassDoc)memberDoc).qualifiedName();
2333 output.beginAnchor(getMemberDocURL(output, memberDoc), title);
2334 output.beginSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
2335 output.print(memberDoc.name());
2336 output.endSpan(CssClass.CLASS_SUMMARY_INHERITED_MEMBER);
2337 output.endAnchor();
2339 output.endCell();
2340 output.endRow();
2341 output.endTable();
2342 output.endDiv(CssClass.TABLE_CONTAINER);
2346 private void collectSpecifiedByRecursive(Set specifyingInterfaces,
2347 ClassDoc classDoc,
2348 MethodDoc methodDoc)
2350 ClassDoc[] interfaces = classDoc.interfaces();
2351 for (int i=0; i<interfaces.length; ++i) {
2352 MethodDoc[] methods = interfaces[i].methods();
2353 for (int j=0; j<methods.length; ++j) {
2354 if (methods[j].name().equals(methodDoc.name())
2355 && methods[j].signature().equals(methodDoc.signature())) {
2356 specifyingInterfaces.add(methods[j]);
2357 break;
2360 collectSpecifiedByRecursive(specifyingInterfaces,
2361 interfaces[i],
2362 methodDoc);
2366 private void printMemberDetails(HtmlPage output,
2367 ProgramElementDoc[] memberDocs, String header,
2368 boolean isOnSerializedPage,
2369 String anchor)
2371 if (memberDocs.length > 0) {
2373 if (null != anchor) {
2374 output.anchorName(anchor);
2377 CssClass sectionClass;
2378 CssClass headerClass;
2379 if (isOnSerializedPage) {
2380 sectionClass = CssClass.SERIALIZED_SECTION;
2381 headerClass = CssClass.SERIALIZED_SECTION_HEADER;
2383 else {
2384 sectionClass = CssClass.SECTION;
2385 headerClass = CssClass.SECTION_HEADER;
2387 output.div(headerClass, header);
2388 output.beginDiv(sectionClass);
2390 for (int i=0; i<memberDocs.length; ++i) {
2391 if (i>0) {
2392 output.hr();
2395 ProgramElementDoc memberDoc = memberDocs[i];
2397 output.anchorName(getMemberAnchor(memberDoc));
2399 output.beginDiv(CssClass.MEMBER_DETAIL);
2400 output.div(CssClass.MEMBER_DETAIL_NAME, memberDoc.name());
2402 StringBuffer synopsis = new StringBuffer();
2403 int synopsisLength = 0;
2405 if (!isOnSerializedPage || !memberDoc.isField()) {
2406 String fullModifiers = getFullModifiers(memberDoc);
2407 synopsis.append(fullModifiers);
2408 synopsisLength += fullModifiers.length();
2411 if (memberDoc.isMethod() || memberDoc.isField()) {
2412 Type type;
2413 if (memberDoc.isMethod()) {
2414 type = ((MethodDoc)memberDoc).returnType();
2416 else {
2417 type = ((FieldDoc)memberDoc).type();
2420 synopsis.append(" ");
2421 synopsisLength ++;
2422 synopsis.append(createTypeHref(output, type, false));
2423 if (null != type.asClassDoc() && type.asClassDoc().isIncluded()) {
2424 synopsisLength += type.asClassDoc().name().length();
2426 else {
2427 synopsisLength += type.qualifiedTypeName().length();
2429 synopsisLength += type.dimension().length();
2432 synopsis.append(" ");
2433 synopsisLength ++;
2435 if (optionLinkSource.getValue() && null != memberDoc.position()) {
2436 ClassDoc containingClass = memberDoc.containingClass();
2437 while (null != containingClass.containingClass()) {
2438 containingClass = containingClass.containingClass();
2440 String href = containingClass.name() + "-source" + filenameExtension + "#line." + memberDoc.position().line();
2441 synopsis.append(output.createHrefString(href, memberDoc.name()));
2443 else {
2444 synopsis.append(memberDoc.name());
2446 synopsisLength += memberDoc.name().length();
2448 if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2449 //printParameters(output, (ExecutableMemberDoc)memberDoc);
2450 synopsis.append("(");
2451 ++ synopsisLength;
2452 StringBuffer paddingLeft = new StringBuffer();
2453 for (int j=0; j<synopsisLength; ++j) {
2454 paddingLeft.append(' ');
2456 Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
2457 for (int j=0; j<parameters.length; ++j) {
2458 Parameter parameter = parameters[j];
2459 synopsis.append(createTypeHref(output, parameter.type(), false));
2460 synopsis.append(" ");
2461 synopsis.append(parameter.name());
2462 if (j < parameters.length - 1) {
2463 synopsis.append(",\n");
2464 synopsis.append(paddingLeft);
2467 synopsis.append(")");
2468 ClassDoc[] exceptions = ((ExecutableMemberDoc)memberDoc).thrownExceptions();
2469 if (exceptions.length > 0) {
2470 synopsis.append("\n throws ");
2471 for (int j=0; j<exceptions.length; ++j) {
2472 ClassDoc exception = exceptions[j];
2473 synopsis.append(createTypeHref(output, exception, false));
2474 if (j < exceptions.length - 1) {
2475 synopsis.append(",\n ");
2481 output.beginDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);
2482 output.print(synopsis.toString());
2483 output.endDiv(CssClass.MEMBER_DETAIL_SYNOPSIS);
2485 output.beginDiv(CssClass.MEMBER_DETAIL_BODY);
2487 Tag[] deprecatedTags = memberDoc.tags("deprecated");
2488 if (deprecatedTags.length > 0) {
2489 output.beginDiv(CssClass.DEPRECATED_INLINE);
2490 output.beginSpan(CssClass.DEPRECATED_HEADER);
2491 output.print("Deprecated. ");
2492 output.endSpan(CssClass.DEPRECATED_HEADER);
2493 output.beginSpan(CssClass.DEPRECATED_BODY);
2495 for (int j=0; j<deprecatedTags.length; ++j) {
2496 printTags(output, memberDoc, deprecatedTags[j].inlineTags(), true);
2498 if (deprecatedTags.length > 0) {
2499 output.endSpan(CssClass.DEPRECATED_BODY);
2500 output.beginDiv(CssClass.DEPRECATED_INLINE);
2503 output.beginDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);
2504 printTags(output, memberDoc, memberDoc.inlineTags(), false);
2505 output.endDiv(CssClass.MEMBER_DETAIL_DESCRIPTION);
2507 if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2509 if (memberDoc.isMethod()) {
2510 Set specifyingInterfaces = new LinkedHashSet();
2511 if (memberDoc.containingClass().isInterface()) {
2512 collectSpecifiedByRecursive(specifyingInterfaces,
2513 memberDoc.containingClass(),
2514 (MethodDoc)memberDoc);
2516 else {
2517 for (ClassDoc cd = memberDoc.containingClass();
2518 null != cd; cd = cd.superclass()) {
2519 collectSpecifiedByRecursive(specifyingInterfaces,
2520 cd,
2521 (MethodDoc)memberDoc);
2525 if (!specifyingInterfaces.isEmpty()
2526 && !isOnSerializedPage) {
2527 output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
2528 output.div(CssClass.MEMBER_DETAIL_SPECIFIED_BY_HEADER, "Specified by:");
2529 Iterator it = specifyingInterfaces.iterator();
2530 while (it.hasNext()) {
2531 MethodDoc specifyingInterfaceMethod = (MethodDoc)it.next();
2532 output.beginDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
2533 output.beginAnchor(getMemberDocURL(output,
2534 specifyingInterfaceMethod));
2535 output.print(memberDoc.name());
2536 output.endAnchor();
2537 output.print(" in interface ");
2538 printType(output, specifyingInterfaceMethod.containingClass());
2539 output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_ITEM);
2541 output.endDiv(CssClass.MEMBER_DETAIL_SPECIFIED_BY_LIST);
2544 ClassDoc overriddenClassDoc = null;
2545 MemberDoc specifyingSuperMethod = null;
2547 for (ClassDoc superclassDoc = memberDoc.containingClass().superclass();
2548 null != superclassDoc && null == overriddenClassDoc;
2549 superclassDoc = superclassDoc.superclass()) {
2551 MethodDoc[] methods = superclassDoc.methods();
2552 for (int j=0; j<methods.length; ++j) {
2553 if (methods[j].name().equals(memberDoc.name())
2554 && methods[j].signature().equals(((MethodDoc)memberDoc).signature())) {
2555 overriddenClassDoc = superclassDoc;
2556 specifyingSuperMethod = methods[j];
2557 break;
2562 if (null != overriddenClassDoc) {
2563 output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
2564 output.div(CssClass.MEMBER_DETAIL_OVERRIDDEN_HEADER, "Overrides:");
2565 output.beginDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);
2567 output.beginAnchor(getMemberDocURL(output,
2568 specifyingSuperMethod));
2569 output.print(memberDoc.name());
2570 output.endAnchor();
2571 output.print(" in interface ");
2572 printType(output, overriddenClassDoc);
2574 output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_ITEM);
2575 output.endDiv(CssClass.MEMBER_DETAIL_OVERRIDDEN_LIST);
2579 if (!optionNoComment.getValue()) {
2581 ExecutableMemberDoc execMemberDoc
2582 = (ExecutableMemberDoc)memberDoc;
2584 if (execMemberDoc.paramTags().length > 0) {
2585 output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
2586 output.div(CssClass.MEMBER_DETAIL_PARAMETER_HEADER, "Parameters:");
2587 Parameter[] parameters = execMemberDoc.parameters();
2588 for (int j=0; j<parameters.length; ++j) {
2589 Parameter parameter = parameters[j];
2590 ParamTag[] paramTags = execMemberDoc.paramTags();
2591 ParamTag paramTag = null;
2592 for (int k=0; k<paramTags.length; ++k) {
2593 if (paramTags[k].parameterName().equals(parameter.name())) {
2594 paramTag = paramTags[k];
2595 break;
2599 if (null != paramTag) {
2600 output.beginDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
2601 output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
2602 output.print(parameter.name());
2603 output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_NAME);
2604 output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
2605 output.print(" - ");
2606 output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_SEPARATOR);
2607 output.beginSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
2608 printTags(output, execMemberDoc, paramTag.inlineTags(), false);
2609 output.endSpan(CssClass.MEMBER_DETAIL_PARAMETER_ITEM_DESCRIPTION);
2610 output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_ITEM);
2613 output.endDiv(CssClass.MEMBER_DETAIL_PARAMETER_LIST);
2616 if (execMemberDoc.isMethod()
2617 && !"void".equals(((MethodDoc)execMemberDoc).returnType().typeName())) {
2619 Tag[] returnTags = execMemberDoc.tags("return");
2620 if (returnTags.length > 0) {
2621 Tag returnTag = returnTags[0];
2623 output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
2624 output.div(CssClass.MEMBER_DETAIL_RETURN_HEADER, "Returns:");
2625 output.beginDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);
2627 printTags(output, execMemberDoc, returnTag.inlineTags(), false);
2629 output.endDiv(CssClass.MEMBER_DETAIL_RETURN_ITEM);
2630 output.endDiv(CssClass.MEMBER_DETAIL_RETURN_LIST);
2634 Set thrownExceptions = getThrownExceptions(execMemberDoc);
2635 boolean haveThrowsInfo = false;
2636 ThrowsTag[] throwsTags = execMemberDoc.throwsTags();
2637 for (int k=0; k<throwsTags.length; ++k) {
2638 ThrowsTag throwsTag = throwsTags[k];
2639 if (null != throwsTags[k].exception()
2640 && (isUncheckedException(throwsTags[k].exception())
2641 || thrownExceptions.contains(throwsTag.exception()))) {
2642 haveThrowsInfo = true;
2643 break;
2647 if (haveThrowsInfo) {
2648 output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2649 output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Throws:");
2651 for (int k=0; k<throwsTags.length; ++k) {
2652 ThrowsTag throwsTag = throwsTags[k];
2653 if (null != throwsTag.exception()
2654 && (isUncheckedException(throwsTag.exception())
2655 || thrownExceptions.contains(throwsTag.exception()))) {
2656 output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
2657 output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
2658 printType(output, throwsTags[k].exception());
2659 output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_NAME);
2660 if (null != throwsTag) {
2661 output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
2662 output.print(" - ");
2663 output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_SEPARATOR);
2664 output.beginSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
2665 printTags(output, execMemberDoc, throwsTag.inlineTags(), false);
2666 output.endSpan(CssClass.MEMBER_DETAIL_THROWN_ITEM_DESCRIPTION);
2668 output.endDiv(CssClass.MEMBER_DETAIL_THROWN_ITEM);
2671 output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2676 if (!optionNoComment.getValue()) {
2678 if (memberDoc.isField()) {
2679 FieldDoc fieldDoc = ((FieldDoc)memberDoc);
2680 if (null != fieldDoc.constantValue()) {
2681 output.beginDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2682 output.div(CssClass.MEMBER_DETAIL_THROWN_HEADER, "Field Value:");
2683 output.div(CssClass.MEMBER_DETAIL_THROWN_ITEM,
2684 fieldDoc.constantValueExpression().toString());
2685 output.endDiv(CssClass.MEMBER_DETAIL_THROWN_LIST);
2689 TagletContext context = new HtmlTagletContext(memberDoc, output, isOnSerializedPage);
2690 printTaglets(output, memberDoc.tags(), context);
2693 output.endDiv(CssClass.MEMBER_DETAIL_BODY);
2694 output.endDiv(CssClass.MEMBER_DETAIL);
2696 output.endDiv(sectionClass);
2701 private void printParameters(HtmlPage output, ExecutableMemberDoc memberDoc)
2703 Parameter[] parameters = memberDoc.parameters();
2704 output.print("(");
2705 for (int j=0; j<parameters.length; ++j) {
2706 if (j > 0) {
2707 output.print(", ");
2709 printType(output, parameters[j].type());
2710 output.print("&nbsp;");
2711 output.print(parameters[j].name());
2713 output.print(")");
2716 private void printProgramElementDocs(HtmlPage output,
2717 ProgramElementDoc[] memberDocs,
2718 String header,
2719 boolean forceOutputHeader,
2720 String anchor)
2722 if (memberDocs.length > 0 || forceOutputHeader) {
2723 output.anchorName(anchor);
2724 output.beginDiv(CssClass.TABLE_CONTAINER);
2725 output.beginTable(CssClass.CLASS_SUMMARY, new String[] { "border", "width" }, new String[] { "1", "100%" });
2726 output.rowDiv(CssClass.TABLE_HEADER, header);
2728 for (int i=0; i<memberDocs.length; ++i) {
2729 ProgramElementDoc memberDoc = memberDocs[i];
2730 output.beginRow();
2732 if (!memberDoc.isConstructor()) {
2733 output.beginCell(CssClass.CLASS_SUMMARY_LEFT);
2734 output.beginDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
2735 output.print(getSummaryModifiers(memberDoc) + " ");
2736 if (memberDoc.isMethod()) {
2737 printType(output, ((MethodDoc)memberDoc).returnType());
2739 else if (memberDoc.isField()) {
2740 printType(output, ((FieldDoc)memberDoc).type());
2742 else if (memberDoc.isInterface()) {
2743 output.print(" interface");
2745 else if (memberDoc.isClass()) {
2746 output.print(" class");
2748 output.endDiv(CssClass.CLASS_SUMMARY_LEFT_SYNOPSIS);
2749 output.endCell();
2752 output.beginCell(CssClass.CLASS_SUMMARY_RIGHT);
2753 output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
2754 output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
2755 if (memberDoc.isClass() || memberDoc.isInterface()) {
2756 output.beginAnchor(getClassDocURL(output, (ClassDoc)memberDoc));
2758 else {
2759 output.beginAnchor("#" + getMemberAnchor(memberDoc));
2761 output.print(memberDoc.name());
2762 output.endAnchor();
2763 if (memberDoc.isConstructor() || memberDoc.isMethod()) {
2764 printParameters(output, (ExecutableMemberDoc)memberDoc);
2766 output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_SYNOPSIS);
2767 Tag[] firstSentenceTags;
2768 Tag[] deprecatedTags = memberDoc.tags("deprecated");
2769 if (deprecatedTags.length > 0) {
2770 firstSentenceTags = deprecatedTags[0].firstSentenceTags();
2772 else {
2773 firstSentenceTags = memberDoc.firstSentenceTags();
2776 if (null != firstSentenceTags && firstSentenceTags.length > 0) {
2777 output.beginDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
2778 if (deprecatedTags.length > 0) {
2779 output.beginDiv(CssClass.DEPRECATED);
2780 output.beginSpan(CssClass.DEPRECATED_HEADER);
2781 output.print("Deprecated. ");
2782 output.endSpan(CssClass.DEPRECATED_HEADER);
2783 output.beginSpan(CssClass.DEPRECATED_BODY);
2785 printTags(output, memberDoc, firstSentenceTags, true);
2786 if (deprecatedTags.length > 0) {
2787 output.endSpan(CssClass.DEPRECATED_BODY);
2788 output.beginDiv(CssClass.DEPRECATED);
2790 output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_DESCRIPTION);
2792 output.endDiv(CssClass.CLASS_SUMMARY_RIGHT_LIST);
2793 output.endCell();
2794 output.endRow();
2796 output.endTable();
2797 output.endDiv(CssClass.TABLE_CONTAINER);
2801 private void printTag(final HtmlPage output,
2802 HtmlRepairer repairer,
2803 Tag tag, boolean firstSentence,
2804 boolean inline,
2805 Doc contextDoc)
2807 TagletContext context = new HtmlTagletContext(contextDoc, output, false);
2808 if (firstSentence) {
2809 output.print(renderInlineTags(tag.firstSentenceTags(), context));
2811 else {
2812 output.print(renderInlineTags(tag.inlineTags(), context));
2816 private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence)
2818 printTags(output, contextDoc, tags, firstSentence, false);
2821 private void printTags(HtmlPage output, Doc contextDoc, Tag[] tags, boolean firstSentence, boolean inline)
2823 if (!optionNoComment.getValue()) {
2824 output.print(renderInlineTags(tags, new HtmlTagletContext(contextDoc, output, false)));
2828 if (!optionNoComment.getValue()) {
2829 output.print(renderInlineTags(tag.firstSentenceTags(), output));
2830 HtmlRepairer repairer = new HtmlRepairer(getRootDoc(),
2831 true, false,
2832 null, null,
2833 true);
2834 for (int i=0; i<tags.length; ++i) {
2835 printTag(output, repairer, tags[i], firstSentence, inline);
2837 output.print(repairer.terminateText());
2842 private String getClassDocURL(HtmlPage output, ClassDoc classDoc)
2844 return output.getPathToRoot()
2845 + "/"
2846 + getPackageURL(classDoc.containingPackage())
2847 + classDoc.name() + filenameExtension;
2850 private String getMemberDocURL(HtmlPage output, ProgramElementDoc memberDoc)
2852 ClassDoc classDoc = memberDoc.containingClass();
2853 PackageDoc packageDoc = classDoc.containingPackage();
2854 ExternalDocSet externalDocSet = null;
2855 if (classDoc.containingPackage().name().length() > 0) {
2856 externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
2858 StringBuffer result = new StringBuffer();
2859 result.append(getClassDocURL(output, classDoc));
2860 result.append('#');
2861 if (null == externalDocSet) {
2862 result.append(getMemberAnchor(memberDoc));
2864 else {
2865 result.append(getMemberAnchor(memberDoc, externalDocSet.isJavadocCompatible()));
2867 return result.toString();
2870 private void printType(HtmlPage output, Type type)
2872 printType(output, type, false);
2875 private void printType(HtmlPage output, Type type, boolean fullyQualified)
2877 output.print(createTypeHref(output, type, fullyQualified));
2880 private String createTypeHref(HtmlPage output, Type type, boolean fullyQualified)
2882 ClassDoc asClassDoc = type.asClassDoc();
2883 String url = null;
2884 if (null != asClassDoc && asClassDoc.isIncluded()) {
2885 url = getClassDocURL(output, asClassDoc);
2887 else if (!type.isPrimitive()) {
2888 if (type.qualifiedTypeName().length() > type.typeName().length()) {
2889 String packageName = type.qualifiedTypeName();
2890 packageName = packageName.substring(0, packageName.length() - type.typeName().length() - 1);
2892 ExternalDocSet externalDocSet
2893 = (ExternalDocSet)packageNameToDocSet.get(packageName);
2894 if (null != externalDocSet) {
2895 url = externalDocSet.getClassDocURL(packageName, type.typeName());
2900 StringBuffer result = new StringBuffer();
2902 if (null != url && null != asClassDoc) {
2903 String parameters = getTypeParameters(asClassDoc);
2904 if (fullyQualified) {
2905 result.append(output.createHrefString(url,possiblyQualifiedName(asClassDoc) + parameters));
2907 else {
2908 StringBuffer title = new StringBuffer();
2909 title.append(getClassTypeName(asClassDoc));
2910 title.append(" in ");
2911 title.append(asClassDoc.containingPackage().name());
2912 result.append(output.createHrefString(url, asClassDoc.name() + parameters, title.toString()));
2915 else {
2916 result.append(possiblyQualifiedName(type));
2918 result.append(type.dimension());
2919 return result.toString();
2922 private void printTaglets(final HtmlPage output, Tag[] tags, TagletContext context)
2924 super.printMainTaglets(tags, context, new TagletPrinter() {
2925 public void printTagletString(String tagletString) {
2926 output.beginDiv(CssClass.TAGLET);
2927 output.print(tagletString);
2928 output.endDiv(CssClass.TAGLET);
2933 private String getPackageURL(PackageDoc packageDoc)
2935 if (packageDoc.name().length() > 0) {
2936 ExternalDocSet externalDocSet = (ExternalDocSet)packageNameToDocSet.get(packageDoc.name());
2937 String url;
2938 if (null != externalDocSet) {
2939 url = externalDocSet.getPackageDocURL(packageDoc.name());
2941 else {
2942 url = packageDoc.name().replace('.', '/');
2944 if (!url.endsWith("/")) {
2945 return url + '/';
2947 else {
2948 return url;
2951 else {
2952 return "";
2956 private String getClassURL(ClassDoc classDoc)
2958 ExternalDocSet externalDocSet = null;
2959 if (classDoc.containingPackage().name().length() > 0) {
2960 externalDocSet = (ExternalDocSet)packageNameToDocSet.get(classDoc.containingPackage().name());
2962 if (null != externalDocSet) {
2963 return externalDocSet.getClassDocURL(classDoc.containingPackage().name(),
2964 classDoc.name());
2966 else {
2967 return getPackageURL(classDoc.containingPackage()) + classDoc.name() + filenameExtension;
2971 protected void run()
2972 throws DocletConfigurationException, IOException
2974 if (optionSerialWarn.getValue()) {
2975 printWarning("Option -serialwarn is currently ignored.");
2978 if (null != optionTitle.getValue()) {
2979 printWarning("Option -title is deprecated.");
2982 if (!optionValidHtml.getValue()) {
2983 printWarning("Option -validhtml hasn't been specified. Generated HTML will not validate.");
2988 boolean warningEmitted = false;
2989 Iterator it = externalDocSets.iterator();
2990 while (it.hasNext()) {
2991 ExternalDocSet externalDocSet = (ExternalDocSet)it.next();
2992 printNotice("Fetching package list for external documentation set.");
2993 try {
2994 externalDocSet.load(getTargetDirectory());
2995 if (!isJavadocCompatibleNames() && externalDocSet.isJavadocCompatible()
2996 && !warningEmitted) {
2997 printWarning("Linking to javadoc-compatible documentation. Generated HTML will not validate ");
2998 warningEmitted = true;
3001 catch (FileNotFoundException e) {
3002 printWarning("Cannot fetch package list from " + externalDocSet.getPackageListDir());
3004 Iterator pit = externalDocSet.getPackageNames().iterator();
3005 while (pit.hasNext()) {
3006 String packageName = (String)pit.next();
3007 packageNameToDocSet.put(packageName, externalDocSet);
3011 printNotice("Building cross-reference information...");
3012 getInterfaceRelations();
3013 getAllSubClasses();
3015 printNotice("Writing overview files...");
3016 printFrameSetPage();
3017 if (!isSinglePackage()) {
3018 printPackagesMenuPage();
3019 printAllClassesMenuPage();
3020 printOverviewPage();
3021 if (!optionNoTree.getValue()) {
3022 printNotice("Writing full tree...");
3023 printFullTreePage();
3026 printPackagesListFile();
3027 printAboutPage();
3028 if (!optionNoIndex.getValue()) {
3029 printNotice("Writing index...");
3030 if (!optionSplitIndex.getValue()) {
3031 printIndexPage();
3033 else {
3034 printSplitIndex();
3037 if (outputHelpPage && !optionNoHelp.getValue()) {
3038 printHelpPage();
3041 // Copy resources
3043 File resourcesDir = new File(getTargetDirectory(),
3044 "resources");
3046 if ((resourcesDir.exists() && !resourcesDir.isDirectory())
3047 || (!resourcesDir.exists() && !resourcesDir.mkdirs())) {
3048 throw new IOException("Cannot create directory " + resourcesDir);
3051 // Copy resources
3053 String[] resourceNames = {
3054 "gjdoc.js",
3055 "gjdochtml-clean-layout.css",
3056 "gjdochtml-clean-color1.css",
3057 "inherit.png",
3058 "xhtml11-target10.dtd",
3061 for (int i=0; i<resourceNames.length; ++i) {
3062 String resourceName = resourceNames[i];
3063 File targetFile = new File(resourcesDir,
3064 resourceName);
3065 InputStream in = getClass().getResourceAsStream("/htmldoclet/" + resourceName);
3066 if (in == null) {
3067 in = new FileInputStream("src/resources/htmldoclet/" + resourceName);
3069 FileOutputStream out = new FileOutputStream(targetFile);
3070 IOToolkit.copyStream(in, out);
3071 in.close();
3072 out.close();
3075 // Copy stylesheets
3077 if (null != optionAddStylesheet.getValue()) {
3078 File addStylesheetTargetFile = new File(resourcesDir,
3079 "user.css");
3081 IOToolkit.copyFile(optionAddStylesheet.getValue(),
3082 addStylesheetTargetFile);
3085 if (null != optionStylesheetFile.getValue()) {
3086 File stylesheetTargetFile = new File(resourcesDir,
3087 "user.css");
3089 IOToolkit.copyFile(optionStylesheetFile.getValue(),
3090 stylesheetTargetFile);
3093 // Write gjdoc.properties
3095 File gjdocPropertiesTargetFile = new File(getTargetDirectory(),
3096 "gjdoc.properties");
3097 writeGjdocProperties(gjdocPropertiesTargetFile);
3100 else {
3101 InputStream cssIn = getClass().getResourceAsStream("/htmldoclet/gjdochtml-vanilla.css");
3102 FileOutputStream cssOut = new FileOutputStream(stylesheetTargetFile);
3103 IOToolkit.copyStream(cssIn, cssOut);
3104 cssIn.close();
3105 cssOut.close();
3109 if (!optionNoDeprecatedList.getValue()) {
3110 printDeprecationPage();
3113 printSerializationPage();
3115 Collection packageDocsCollection = getAllPackages();
3116 PackageDoc[] packageDocs
3117 = (PackageDoc[])packageDocsCollection.toArray(new PackageDoc[0]);
3119 for (int i=0; i<packageDocs.length; ++i) {
3120 PackageDoc packageDoc = packageDocs[i];
3121 File packageDir = new File(getTargetDirectory(),
3122 packageDoc.name().replace('.', File.separatorChar));
3123 if (!packageDir.exists() && !packageDir.mkdirs()) {
3124 throw new IOException("Couldn't create directory " + packageDir);
3126 try {
3127 List packageSourceDirs = getPackageSourceDirs(packageDoc);
3128 Iterator pdIt = packageSourceDirs.iterator();
3129 while (pdIt.hasNext()) {
3130 File sourcePackageDir = (File)pdIt.next();
3131 copyDocFiles(sourcePackageDir, packageDir);
3134 catch (IOException ignore) {
3136 String pathToRoot = getPathToRoot(packageDir, getTargetDirectory());
3137 String packageName = packageDoc.name();
3138 if (0 == packageName.length()) {
3139 packageName = "<unnamed>";
3141 printNotice("Writing HTML files for package " + packageName);
3142 printPackagePage(packageDir, pathToRoot, packageDoc,
3143 (i > 0) ? packageDocs[i - 1] : null,
3144 (i < packageDocs.length - 1) ? packageDocs[i + 1] : null);
3145 if (!optionNoTree.getValue()) {
3146 printPackageTreePage(packageDir, pathToRoot, packageDoc);
3148 printPackageClassesMenuPage(packageDir, pathToRoot, packageDoc);
3149 ClassDoc[] classDocs = packageDoc.allClasses();
3150 for (int j=0; j<classDocs.length; ++j) {
3151 ClassDoc classDoc = classDocs[j];
3152 if (classDoc.isIncluded()) {
3153 printClassPage(packageDir, pathToRoot,
3154 classDocs[j],
3155 (j > 0) ? classDocs[j - 1] : null,
3156 (j < classDocs.length - 1) ? classDocs[j + 1] : null
3158 if (optionUse.getValue()) {
3159 printClassUsagePage(packageDir, pathToRoot, classDocs[j]);
3161 if (optionLinkSource.getValue() && null == classDoc.containingClass()) {
3162 try {
3163 File sourceFile = getSourceFile(classDoc);
3165 Java2xhtml java2xhtml = new Java2xhtml();
3166 Properties properties = new Properties();
3167 properties.setProperty("isCodeSnippet", "true");
3168 properties.setProperty("hasLineNumbers", "true");
3169 java2xhtml.setProperties(properties);
3171 StringWriter sourceBuffer = new StringWriter();
3172 FileReader sourceReader = new FileReader(sourceFile);
3173 IOToolkit.copyStream(sourceReader, sourceBuffer);
3174 sourceReader.close();
3175 String result = java2xhtml.makeHTML(sourceBuffer.getBuffer(), sourceFile.getName());
3177 printSourcePage(packageDir,
3178 classDoc,
3179 result);
3181 catch (IOException e) {
3182 printWarning("Cannot locate source file for class " + classDoc.qualifiedTypeName());
3190 private String getPathToRoot(File subDir, File rootDir)
3192 StringBuffer result = new StringBuffer();
3193 while (!subDir.equals(rootDir)) {
3194 if (result.length() > 0) {
3195 result.append("/");
3197 subDir = subDir.getParentFile();
3198 result.append("..");
3200 if (0 == result.length()) {
3201 result.append(".");
3203 return result.toString();
3206 private String getClassTypeName(ClassDoc classDoc)
3208 if (classDoc.isInterface()) {
3209 return "Interface";
3211 else {
3212 return "Class";
3216 private String getClassTypeKeyword(ClassDoc classDoc)
3218 if (classDoc.isInterface()) {
3219 return "interface";
3221 else {
3222 return "class";
3226 private String getMemberAnchor(ProgramElementDoc memberDoc)
3228 return getMemberAnchor(memberDoc, isJavadocCompatibleNames());
3231 private String getMemberAnchor(ProgramElementDoc memberDoc, boolean javadocCompatibility)
3233 StringBuffer anchor = new StringBuffer();
3234 anchor.append(memberDoc.name());
3235 if (memberDoc.isConstructor() || memberDoc.isMethod()) {
3236 if (javadocCompatibility) {
3237 anchor.append(((ExecutableMemberDoc)memberDoc).signature());
3239 else {
3240 anchor.append(':');
3241 Parameter[] parameters = ((ExecutableMemberDoc)memberDoc).parameters();
3242 for (int i=0; i<parameters.length; ++i) {
3243 anchor.append(parameters[i].type().typeName());
3244 for (int j=0; j<parameters[i].type().dimension().length()/2; ++j) {
3245 anchor.append('-');
3247 if (i < parameters.length - 1) {
3248 anchor.append(':');
3253 return anchor.toString();
3256 private String getFullModifiers(ProgramElementDoc memberDoc)
3258 StringBuffer result = new StringBuffer();
3259 if (memberDoc.isPackagePrivate()) {
3260 result.append("(package private) ");
3262 result.append(memberDoc.modifiers());
3263 if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
3264 || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
3265 result.append(" abstract");
3267 return result.toString();
3270 private String getSummaryModifiers(ProgramElementDoc memberDoc)
3272 StringBuffer result = new StringBuffer();
3273 if (memberDoc.isPackagePrivate()) {
3274 result.append("(package private) ");
3276 else if (memberDoc.isPrivate()) {
3277 result.append("private ");
3279 else if (memberDoc.isProtected()) {
3280 result.append("protected ");
3282 if (memberDoc.isStatic()) {
3283 result.append("static");
3285 else if ((memberDoc.isClass() && ((ClassDoc)memberDoc).isAbstract())
3286 || (memberDoc.isMethod() && ((MethodDoc)memberDoc).isAbstract())) {
3287 result.append("abstract");
3289 return result.toString();
3292 protected DocletOption[] getOptions()
3294 return options;
3297 private DocletOptionFlag optionNoNavBar =
3298 new DocletOptionFlag("-nonavbar");
3300 private DocletOptionFlag optionNoTree =
3301 new DocletOptionFlag("-notree");
3303 private DocletOptionFlag optionNoDeprecatedList =
3304 new DocletOptionFlag("-nodeprecatedlist");
3306 private DocletOptionFlag optionNoIndex =
3307 new DocletOptionFlag("-noindex");
3309 private DocletOptionFlag optionUse =
3310 new DocletOptionFlag("-use");
3312 private DocletOptionFlag optionNoHelp =
3313 new DocletOptionFlag("-nohelp");
3315 private DocletOptionFlag optionNoComment =
3316 new DocletOptionFlag("-nocomment");
3318 private DocletOptionFlag optionSerialWarn =
3319 new DocletOptionFlag("-serialwarn");
3321 private DocletOptionFlag optionSplitIndex =
3322 new DocletOptionFlag("-splitindex");
3324 private DocletOptionString optionHeader =
3325 new DocletOptionString("-header");
3327 private DocletOptionString optionFooter =
3328 new DocletOptionString("-footer");
3330 private DocletOptionString optionBottom =
3331 new DocletOptionString("-bottom");
3333 private DocletOptionString optionWindowTitle =
3334 new DocletOptionString("-windowtitle");
3336 private DocletOptionString optionDocTitle =
3337 new DocletOptionString("-doctitle");
3339 private DocletOptionString optionTitle =
3340 new DocletOptionString("-title");
3342 private DocletOptionFile optionHelpFile =
3343 new DocletOptionFile("-helpfile");
3345 private DocletOptionFile optionStylesheetFile =
3346 new DocletOptionFile("-stylesheetfile");
3348 private DocletOptionFlag optionLinkSource =
3349 new DocletOptionFlag("-linksource");
3351 private DocletOption optionLink =
3352 new DocletOption("-link") {
3354 public int getLength()
3356 return 2;
3359 public boolean set(String[] optionArr)
3361 externalDocSets.add(new ExternalDocSet(optionArr[1], null));
3362 return true;
3366 private DocletOption optionLinkOffline =
3367 new DocletOption("-linkoffline") {
3369 public int getLength()
3371 return 3;
3374 public boolean set(String[] optionArr)
3376 externalDocSets.add(new ExternalDocSet(optionArr[1], optionArr[2]));
3377 return true;
3381 private DocletOptionString optionDocEncoding =
3382 new DocletOptionString("-docencoding");
3384 private DocletOptionString optionEncoding =
3385 new DocletOptionString("-encoding");
3387 private DocletOptionString optionCharset =
3388 new DocletOptionString("-charset");
3390 private DocletOptionFile optionAddStylesheet =
3391 new DocletOptionFile("-addstylesheet");
3393 private DocletOptionFlag optionValidHtml =
3394 new DocletOptionFlag("-validhtml");
3396 private DocletOptionString optionBaseUrl =
3397 new DocletOptionString("-baseurl");
3399 private DocletOption[] options =
3401 optionNoNavBar,
3402 optionNoTree,
3403 optionNoDeprecatedList,
3404 optionNoIndex,
3405 optionNoHelp,
3406 optionNoComment,
3407 optionUse,
3408 optionSplitIndex,
3409 optionHeader,
3410 optionFooter,
3411 optionBottom,
3412 optionHelpFile,
3413 optionStylesheetFile,
3414 optionWindowTitle,
3415 optionDocTitle,
3416 optionTitle,
3417 optionLinkSource,
3418 optionLink,
3419 optionLinkOffline,
3420 optionDocEncoding,
3421 optionEncoding,
3422 optionCharset,
3423 optionAddStylesheet,
3424 optionValidHtml,
3425 optionBaseUrl,
3428 static {
3429 setInstance(new HtmlDoclet());
3432 private static String replaceDocRoot(HtmlPage output, String str)
3434 return StringToolkit.replace(str, "{@docRoot}", output.getPathToRoot());
3437 private String getOutputDocEncoding()
3439 String encoding = optionDocEncoding.getValue();
3441 if (null == encoding) {
3442 encoding = optionEncoding.getValue();
3445 return encoding;
3448 private String getOutputCharset()
3450 if (null == outputCharset) {
3452 if (null != optionCharset.getValue()) {
3453 outputCharset = optionCharset.getValue();
3455 else {
3456 String fileEncoding = System.getProperty("file.encoding");
3457 if (null != fileEncoding) {
3458 try {
3459 outputCharset = Charset.forName(fileEncoding).name();
3461 catch (Exception ignore) {
3465 if (null == outputCharset) {
3466 printWarning("Cannot determine platform default charset, falling back to ISO-8859-1.");
3467 outputCharset = "ISO-8859-1";
3471 return outputCharset;
3474 public InlineTagRenderer getInlineTagRenderer()
3476 return this;
3479 public String renderInlineTags(Tag[] tags, TagletContext context)
3481 StringBuffer result = new StringBuffer();
3483 HtmlRepairer repairer = new HtmlRepairer(getRootDoc(),
3484 true, false,
3485 null, null,
3486 true);
3488 for (int i=0; i<tags.length; ++i) {
3490 Tag tag = tags[i];
3492 if ("Text".equals(tag.name())) {
3493 result.append(repairer.getWellformedHTML(tag.text()));
3495 else if ("@link".equals(tag.name())) {
3496 result.append(renderSeeTag((SeeTag)tag, context, false));
3498 else if ("@linkplain".equals(tag.name())) {
3499 result.append(renderSeeTag((SeeTag)tag, context, true));
3501 else if ("@docRoot".equals(tag.name())) {
3502 result.append(((HtmlTagletContext)context).getOutput().getPathToRoot());
3504 else {
3505 //TagletContext context = TagletContext.OVERVIEW; // FIXME
3506 Taglet taglet = (Taglet)tagletMap.get(tag.name().substring(1));
3507 if (null != taglet) {
3508 if (taglet instanceof GnuExtendedTaglet) {
3509 result.append(((GnuExtendedTaglet)taglet).toString(tag, context));
3511 else {
3512 result.append(taglet.toString(tag));
3517 result.append(repairer.terminateText());
3518 return result.toString();
3521 public String renderSeeTag(SeeTag seeTag, TagletContext context, boolean plainFont)
3523 StringBuffer result = new StringBuffer();
3525 String href = null;
3526 String label = null;
3527 MemberDoc referencedMember = seeTag.referencedMember();
3528 if (null != seeTag.referencedClass()) {
3530 href = getClassDocURL(((HtmlTagletContext)context).getOutput(), seeTag.referencedClass());
3532 Doc doc = context.getDoc();
3533 ClassDoc classDoc = null;
3534 if (doc.isClass() || doc.isInterface()) {
3535 classDoc = (ClassDoc)doc;
3537 else if (doc.isField() || doc.isMethod() || doc.isConstructor()) {
3538 classDoc = ((MemberDoc)doc).containingClass();
3541 if (null == referencedMember
3542 || seeTag.referencedClass() != classDoc
3543 || ((HtmlTagletContext)context).isOnSerializedPage()) {
3545 if (!seeTag.referencedClass().isIncluded()) {
3546 label = possiblyQualifiedName(seeTag.referencedClass());
3548 else {
3549 label = seeTag.referencedClass().typeName();
3551 if (null != referencedMember) {
3552 label += '.';
3555 else {
3556 label = "";
3559 if (null != referencedMember) {
3560 label += referencedMember.name();
3561 if (referencedMember.isMethod() || referencedMember.isConstructor()) {
3562 label += ((ExecutableMemberDoc)referencedMember).flatSignature();
3564 href += '#' + getMemberAnchor(referencedMember);
3566 else if (null != seeTag.referencedMemberName()) {
3567 href = null;
3570 else {
3571 String referencedClassName = seeTag.referencedClassName();
3573 if (null != referencedClassName) {
3575 String referencedPackageName = null;
3577 Iterator it = packageNameToDocSet.keySet().iterator();
3578 while (it.hasNext()) {
3579 String packageName = (String)it.next();
3580 if ((null == referencedPackageName
3581 || packageName.length() > referencedPackageName.length())
3582 && referencedClassName.startsWith(packageName + '.')) {
3583 referencedPackageName = packageName;
3587 if (null != referencedPackageName) {
3588 ExternalDocSet externalDocSet
3589 = (ExternalDocSet)packageNameToDocSet.get(referencedPackageName);
3591 String className = referencedClassName.substring(referencedPackageName.length() + 1);
3592 href = externalDocSet.getClassDocURL(referencedPackageName,
3593 className);
3594 label = className;
3596 String referencedMemberName = seeTag.referencedMemberName();
3598 if (null != referencedMemberName) {
3599 label += '.';
3600 label += referencedMemberName;
3601 href += '#' + transformReferencedMemberName(referencedMemberName,
3602 externalDocSet.isJavadocCompatible());
3604 else if (null != seeTag.referencedMemberName()) {
3605 href = null;
3611 if (null != seeTag.label()
3612 && seeTag.label().length() > 0) {
3613 label = seeTag.label();
3616 if (null == label) {
3617 label = seeTag.text();
3618 if (label.startsWith("#")) {
3619 label = label.substring(1);
3621 else {
3622 label = label.replace('#', '.');
3624 label.trim();
3627 if (null != href) {
3628 result.append("<a href=\"");
3629 result.append(href);
3630 result.append("\">");
3631 if (!plainFont) {
3632 result.append("<code>");
3634 result.append(label);
3635 if (!plainFont) {
3636 result.append("</code>");
3638 result.append("</a>");
3640 else {
3641 if (!plainFont) {
3642 result.append("<code>");
3644 result.append(label);
3645 if (!plainFont) {
3646 result.append("</code>");
3650 return result.toString();
3653 protected String renderTag(String tagName, Tag[] tags, TagletContext context)
3655 Doc doc = context.getDoc();
3657 if ("see".equals(tagName)
3658 && ((tags.length > 0)
3659 || (doc.isClass()
3660 && (((ClassDoc)doc).isSerializable()
3661 || ((ClassDoc)doc).isExternalizable())))) {
3663 StringBuffer result = new StringBuffer();
3664 result.append("<dl class=\"tag list\">");
3665 result.append("<dt class=\"tag section header\"><b>");
3666 result.append("See Also:");
3667 result.append("</b></dt>");
3669 boolean oneLine = true;
3671 if (oneLine) {
3672 result.append("<dd>");
3675 for (int i = 0; i < tags.length; ++i) {
3676 if (oneLine) {
3677 if (i > 0) {
3678 result.append(", ");
3681 else {
3682 result.append("<dd>");
3684 result.append(renderSeeTag((SeeTag)tags[i], context, false));
3685 if (!oneLine) {
3686 result.append("</dd>");
3690 if ((doc instanceof ClassDoc)
3691 && (((ClassDoc)doc).isSerializable() || ((ClassDoc)doc).isExternalizable())) {
3692 if (tags.length > 0) {
3693 result.append(", ");
3695 HtmlPage output = ((HtmlTagletContext)context).getOutput();
3696 result.append("<a href=\"" + output.getPathToRoot() + "/serialized-form" + filenameExtension + "#" + ((ClassDoc)doc).qualifiedName() + "\">Serialized Form</a>");
3699 if (oneLine) {
3700 result.append("</dd>");
3702 result.append("</dl>");
3703 return result.toString();
3705 else if (tags.length > 0
3706 && "serial".equals(tagName)
3707 && ((HtmlTagletContext)context).isOnSerializedPage()) {
3709 return renderInlineTags(tags[0].inlineTags(), context);
3711 else {
3712 return "";
3716 private String getWindowTitle()
3718 if (null == optionWindowTitle.getValue()) {
3719 return "Generated API Documentation";
3721 else {
3722 return optionWindowTitle.getValue();
3726 private String getPageTitle(String title)
3728 if (null == optionWindowTitle.getValue()) {
3729 return title;
3731 else {
3732 return title + " (" + optionWindowTitle.getValue() + ")";
3736 protected String getDocletVersion()
3738 if (null == docletVersion) {
3739 docletVersion = gnu.classpath.Configuration.CLASSPATH_VERSION;
3741 return docletVersion;
3744 private Map getStylesheets()
3746 Map sheets = new HashMap();
3747 if (null != optionStylesheetFile.getValue()) {
3748 sheets.put("User-specified", new String[] {
3749 "resources/user.css"
3752 else {
3753 List cleanSheets = new LinkedList();
3754 cleanSheets.add("resources/gjdochtml-clean-layout.css");
3755 cleanSheets.add("resources/gjdochtml-clean-color1.css");
3756 if (null != optionAddStylesheet.getValue()) {
3757 cleanSheets.add("resources/user.css");
3759 sheets.put("GNU Clean", cleanSheets.toArray(new String[0]));
3761 return sheets;
3764 protected boolean isSinglePackage()
3766 if (getRootDoc().firstSentenceTags().length > 0) {
3767 return false;
3769 else if (null != optionDocTitle.getValue()
3770 || null != optionTitle.getValue()) {
3771 return false;
3773 else {
3774 return super.isSinglePackage();
3778 private String getTypeParameters(ClassDoc classDoc)
3780 String parameters = "";
3781 TypeVariable[] params = classDoc.typeParameters();
3782 if (params != null && params.length > 0)
3784 parameters = "&lt;";
3785 for (int a = 0; a < params.length; ++a)
3787 parameters += params[a].typeName();
3788 Type[] bounds = params[a].bounds();
3789 if (bounds != null)
3791 parameters += " extends ";
3792 for (int b = 0; a < bounds.length; ++b)
3794 parameters += bounds[a];
3795 if (b != bounds.length - 1)
3796 parameters += " & ";
3799 if (a != params.length - 1)
3800 parameters += ",";
3802 parameters += "&gt;";
3804 return parameters;
3807 private String transformReferencedMemberName(String referencedMemberName,
3808 boolean javadocCompatibility)
3810 if (!javadocCompatibility) {
3811 StringBuffer result = new StringBuffer();
3812 for (int i=0; i<referencedMemberName.length(); ++i) {
3813 char c = referencedMemberName.charAt(i);
3814 switch (c) {
3815 case '(': result.append(':'); break;
3816 case ')': break;
3817 case ',': result.append(':'); break;
3818 case '[': result.append('-'); break;
3819 case ']': break;
3820 default: result.append(c); break;
3823 return result.toString();
3825 else {
3826 return referencedMemberName;
3830 public void writeGjdocProperties(File outputFile)
3831 throws IOException
3833 Properties properties = new Properties();
3834 properties.setProperty("gjdoc.version", getDocletVersion());
3835 properties.setProperty("gjdoc.compat", Boolean.toString(isJavadocCompatibleNames()));
3837 FileOutputStream out = new FileOutputStream(outputFile);
3838 properties.store(out, "GNU Gjdoc API Documentation Set Descriptor");
3839 out.close();
3842 public boolean isJavadocCompatibleNames()
3844 return !optionValidHtml.getValue();
3847 private HtmlPage newHtmlPage(File file,
3848 String pathToRoot)
3849 throws IOException
3851 return new HtmlPage(file,
3852 pathToRoot,
3853 getOutputDocEncoding(),
3854 optionBaseUrl.getValue(),
3855 getTargetDirectory());
3858 private HtmlPage newHtmlPage(File file,
3859 String pathToRoot,
3860 String docType)
3861 throws IOException
3863 return new HtmlPage(file,
3864 pathToRoot,
3865 getOutputDocEncoding(),
3866 optionBaseUrl.getValue(),
3867 getTargetDirectory(),
3868 docType);