home *** CD-ROM | disk | FTP | other *** search
/ Internet News 1999 October / INEWS_10_CD.ISO / pc / jdk / jdk1.2.2 / docs / tooldocs / javadoc / source / standard / HtmlStandardWriter.java < prev    next >
Encoding:
Java Source  |  1999-09-19  |  43.2 KB  |  1,390 lines

  1. /*
  2.  * @(#)HtmlStandardWriter.java    1.28 98/08/18
  3.  *
  4.  * Copyright 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package com.sun.tools.doclets.standard;
  16.  
  17. import com.sun.tools.doclets.*;
  18. import com.sun.javadoc.*;
  19. import java.io.*;
  20. import java.util.*;
  21. import java.lang.*;
  22. import java.text.MessageFormat;
  23.  
  24.  
  25. /** 
  26. * Class for the Html Format Code Generation specific to JavaDoc.
  27. * This Class contains methods related to the Html Code Generation which 
  28. * are used extensively while generating the entire documentation.
  29. *
  30. * @since JDK1.2
  31. * @author Atul M Dambalkar
  32. * @author Robert Field
  33. */
  34. public class HtmlStandardWriter extends HtmlDocWriter {
  35.   
  36.     /**
  37.      * Destination directory name as specified on the command line.
  38.      */
  39.     public static final String destdir = Standard.configuration().destdirname; 
  40.  
  41.     /**
  42.      * Relative path from the file getting generated to the current or the 
  43.      * destination directory. For example, if the file getting generated is
  44.      * "java/lang/Object.html", then the relative path string is "../..".
  45.      */
  46.     public String relativepath = ""; 
  47.  
  48.     /**
  49.      * Directory path from the current or the destination directory to the file
  50.      * getting generated. For example, if the file getting generated is 
  51.      * "java/lang/Object.html", then the path string is "java/lang".
  52.      */    
  53.     public String path = "";
  54.  
  55.     /**
  56.      * Name of the file getting generated. If the file getting generated is 
  57.      * "java/lang/Object.html", then the filename is "Object.html".
  58.      */   
  59.     public String filename = "";
  60.  
  61.     /**
  62.      * Relative path from the destination directory to the current directory.
  63.      * For example if the destination directory is "core/api/docs", then the
  64.      * backpat string will be "../../".
  65.      */
  66.     public String backpath = DirectoryManager.getBackPath(destdir);
  67.  
  68.     /**
  69.      * The display length used for indentation while generating the class page.
  70.      */
  71.     public int displayLength = 0;
  72.  
  73.     /** 
  74.      * The classdoc for the class file getting generated.
  75.      */ 
  76.     public static ClassDoc currentcd = null;  // Set this classdoc in the
  77.                                               // ClassWriter.
  78.  
  79.     /**
  80.      * Constructor to construct the HtmlStandardWriter object.
  81.      *
  82.      * @param filename File to be generated.
  83.      */
  84.     public HtmlStandardWriter(String filename) throws IOException {
  85.         super(filename);
  86.         this.filename = filename;
  87.     }
  88.  
  89.     /**
  90.      * Constructor to construct the HtmlStandardWriter object.
  91.      *
  92.      * @param path         Value for the variable {@link path}.
  93.      * @param filename     File to be generated.
  94.      * @param relativepath Value for the variable {@link relativepath}.
  95.      */
  96.     public HtmlStandardWriter(String path, String filename, 
  97.                               String relativepath) throws IOException {
  98.         super(path, filename);
  99.         this.path = path;
  100.         this.relativepath = relativepath;
  101.         this.filename = filename;
  102.     }
  103.  
  104.     /**
  105.      * Print Html Hyper Link, with target frame.
  106.      *
  107.      * @param link String name of the file.
  108.      * @param where Position in the file
  109.      * @param target Name of the target frame.
  110.      * @param label Tag for the link.
  111.      * @param bold Whether the label should be bold or not?
  112.      */
  113.     public void printTargetHyperLink(String link, String where,
  114.                                      String target, String label,
  115.                                      boolean bold) {
  116.         print(getTargetHyperLink(link, where, target, label, bold));
  117.     }
  118.  
  119.     /**
  120.      * Get Html Hyper Link, with target frame.
  121.      *
  122.      * @param link String name of the file.
  123.      * @param where Position in the file
  124.      * @param target Name of the target frame.
  125.      * @param label Tag for the link.
  126.      * @param bold Whether the label should be bold or not?
  127.      */
  128.     public String getTargetHyperLink(String link, String where,
  129.                                      String target, String label,
  130.                                      boolean bold) {
  131.         StringBuffer str = new StringBuffer();
  132.         str.append("<A HREF=\"");
  133.         str.append(link);
  134.         if (where.length() > 0) {
  135.             str.append("#" + where);
  136.         }
  137.         str.append("\"");
  138.         str.append(" TARGET=\"");
  139.         str.append(target);
  140.         str.append("\">");
  141.         if(bold) {
  142.             str.append("<B>");
  143.         }
  144.         str.append(label);
  145.         if(bold) {
  146.             str.append("</B>");   
  147.         }
  148.         str.append("</A>");
  149.         return str.toString();
  150.     }
  151.  
  152.     /**
  153.      * Print Html Hyper Link, with target frame.
  154.      *
  155.      * @param link String name of the file.
  156.      * @param target Name of the target frame.
  157.      * @param label Tag for the link.
  158.      * @param bold Whether the label should be bold or not?
  159.      */
  160.     public void printTargetHyperLink(String link, String target, 
  161.                                      String label, boolean bold) {
  162.        printTargetHyperLink(link, "", target, label, bold);
  163.     }
  164.  
  165.  
  166.     /**
  167.      * Print bold Html Hyper Link, with target frame. The label will be bold.
  168.      *
  169.      * @param link String name of the file.
  170.      * @param target Name of the target frame.
  171.      * @param label Tag for the link.
  172.      */
  173.     public void printBoldTargetHyperLink(String link, String target, 
  174.                                          String label) {
  175.         printTargetHyperLink(link, target, label, true);
  176.     }
  177.  
  178.     /**
  179.      * Print Html Hyper Link, with target frame.
  180.      *
  181.      * @param link String name of the file.
  182.      * @param target Name of the target frame.
  183.      * @param label Tag for the link.
  184.      */
  185.     public void printTargetHyperLink(String link, String target, 
  186.                                      String label) {
  187.        printTargetHyperLink(link, "", target, label, false);
  188.     }
  189.  
  190.     /**
  191.      * Print Class link, with target frame.
  192.      *
  193.      * @param cd The class to which link is.
  194.      * @param target Name of the target frame.
  195.      */
  196.     public void printTargetClassLink(ClassDoc cd, String target) {
  197.         String filename = cd.name() + ".html";
  198.         printTargetHyperLink(filename, target, 
  199.                              (cd.isInterface())? 
  200.                                  italicsText(cd.name()): cd.name());
  201.     }
  202.  
  203.     /**
  204.      * Print Package link, with target frame.
  205.      *
  206.      * @param pd The link will be to the "package-summary.html" page for this 
  207.      * package.
  208.      * @param target Name of the target frame.
  209.      * @param label Tag for the link.
  210.      */
  211.     public void printTargetPackageLink(PackageDoc pd, String target, 
  212.                                        String label) {
  213.         printTargetHyperLink(pathString(pd, "package-summary.html"), 
  214.                              target, label);
  215.     }
  216.     /**
  217.      * Print the html file header. Also print Html page title and stylesheet
  218.      * default properties.
  219.      * 
  220.      * @param title String title for the generated html file.
  221.      */
  222.     public void printHeader(String title) {
  223.         println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">");
  224.         println("<!--NewPage-->");
  225.         html();
  226.         head();
  227.         print("<!-- Generated by javadoc on ");
  228.         print(today());
  229.         println(" -->");
  230.         title();
  231.         println(title);
  232.         titleEnd();
  233.         printStyleSheetProperties();
  234.         headEnd();
  235.         body("white");
  236.     }
  237.  
  238.     /**
  239.      * Print user specified header and the footer.
  240.      * 
  241.      * @param header if true print the user provided header else print the
  242.      * user provided footer.
  243.      */
  244.     public void printUserHeaderFooter(boolean header) {
  245.         em();
  246.         if (header) {
  247.             print(Standard.configuration().header);
  248.         } else {
  249.             if (Standard.configuration().footer.length() != 0) {
  250.                 print(Standard.configuration().footer);
  251.             } else {
  252.                 print(Standard.configuration().header);
  253.         }
  254.         }
  255.         emEnd();
  256.     }
  257.  
  258.     /**
  259.      * Print the user specified bottom.
  260.      */ 
  261.     public void printBottom() {
  262.         hr();
  263.         print(Standard.configuration().bottom);  // usually empty
  264.     } 
  265.  
  266.     /**
  267.      * Print the navigation bar for the Html page at the top and and the bottom.
  268.      *
  269.      * @param header If true print navigation bar at the top of the page else
  270.      * print the nevigation bar at the bottom.
  271.      */
  272.     protected void navLinks(boolean header) {
  273.         println("");
  274.         println("<!-- ========== START OF NAVBAR ========== -->");
  275.         if (!Standard.configuration().nonavbar) {
  276.             if (header) {
  277.                 anchor("navbar_top");
  278.             } else {
  279.                 anchor("navbar_bottom");
  280.             }
  281.             table(0, "100%", 1, 0);
  282.             tr();
  283.             tdColspanBgcolorStyle(2, "#EEEEFF", "NavBarCell1");
  284.             println("");
  285.             if (header) {
  286.                 anchor("navbar_top_firstrow");
  287.             } else {
  288.                 anchor("navbar_bottom_firstrow");
  289.             }
  290.             table(0, 0, 3);
  291.             print("  ");
  292.             trAlignVAlign("center", "top");
  293.  
  294.         if (Standard.configuration().createoverview) {
  295.                 navLinkContents();
  296.             }
  297.  
  298.             if (Standard.configuration().packages.length > 0) {
  299.                 navLinkPackage();
  300.             }
  301.  
  302.             navLinkClass();
  303.  
  304.             if(Standard.configuration().classuse) {
  305.                 navLinkClassUse();
  306.             }
  307.             if(Standard.configuration().createtree) {
  308.                 navLinkTree();
  309.             }
  310.             if(!(Standard.configuration().nodeprecated || 
  311.                     Standard.configuration().nodeprecatedlist)) {
  312.                 navLinkDeprecated();
  313.             }
  314.             if(Standard.configuration().createindex) {
  315.                 navLinkIndex();
  316.             }
  317.             if (!Standard.configuration().nohelp) {
  318.                 navLinkHelp();
  319.             }
  320.             print("  ");
  321.             trEnd();
  322.             tableEnd();
  323.             tdEnd();
  324.  
  325.             tdAlignVAlignRowspan("right", "top", 3);
  326.  
  327.             printUserHeaderFooter(header);
  328.             tdEnd();
  329.             trEnd();
  330.             println("");
  331.  
  332.             tr();
  333.             tdBgcolorStyle("white", "NavBarCell2");
  334.             font("-2");
  335.             space();
  336.             navLinkPrevious();
  337.             space();
  338.             println("");
  339.             space();
  340.             navLinkNext();
  341.             fontEnd();
  342.             tdEnd();
  343.  
  344.             tdBgcolorStyle("white", "NavBarCell2");
  345.             font("-2");
  346.             print("  ");
  347.             navShowLists();
  348.             print("  ");
  349.             space();
  350.             println("");
  351.             space();
  352.             navHideLists();
  353.             fontEnd();
  354.             tdEnd();
  355.  
  356.             trEnd();
  357.             
  358.             printSummaryDetailLinks();
  359.  
  360.             tableEnd();
  361.             println("<!-- =========== END OF NAVBAR =========== -->");
  362.             println("");
  363.         }
  364.     }  
  365.  
  366.     /**
  367.      * Do nothing. This is the default method. 
  368.      */
  369.     protected void printSummaryDetailLinks() {
  370.     }
  371.  
  372.     /**
  373.      * Print link to the "overview-summary.html" page.
  374.      */
  375.     protected void navLinkContents() {
  376.         navCellStart();
  377.         printHyperLink(relativepath + "overview-summary.html", "",
  378.                        getText("doclet.Overview"), true, "NavBarFont1");
  379.         navCellEnd();
  380.     }
  381.                                 
  382.     /**
  383.      * Description for a cell in the navigation bar.
  384.      */
  385.     protected void navCellStart() {
  386.         print("  ");
  387.         tdBgcolorStyle("#EEEEFF", "NavBarCell1");
  388.         print("    ");
  389.     }
  390.  
  391.     /**
  392.      * Description for a cell in the navigation bar, but with reverse 
  393.      * high-light effect.
  394.      */
  395.     protected void navCellRevStart() {
  396.         print("  ");
  397.         tdBgcolorStyle("#FFFFFF", "NavBarCell1Rev");
  398.         print(" ");
  399.         space();
  400.     }
  401.  
  402.     /**
  403.      * Closing tag for navigation bar cell.
  404.      */
  405.     protected void navCellEnd() {
  406.         space();
  407.         tdEnd();
  408.     }
  409.  
  410.     /**
  411.      * Print link to the "package-summary.html" page for the package passed.
  412.      *
  413.      * @param pkg Package to which link will be generated.
  414.      */
  415.     protected void navLinkPackage(PackageDoc pkg) {
  416.         printPackageLink(pkg, getFontColor("NavBarFont1") + getBold() + 
  417.                          getText("doclet.Package") + 
  418.                          getBoldEnd() + getFontEnd());
  419.     }
  420.  
  421.     /**
  422.      * Print the word "Package" in the navigation bar cell, to indicate that
  423.      * link is not available here.
  424.      */
  425.     protected void navLinkPackage() {
  426.         navCellStart();
  427.         fontStyle("NavBarFont1");
  428.         printText("doclet.Package");
  429.         fontEnd();
  430.         navCellEnd();
  431.     }
  432.                                 
  433.     /**
  434.      * Print the word "Use" in the navigation bar cell, to indicate that link 
  435.      * is not available.
  436.      */
  437.     protected void navLinkClassUse() {
  438.         navCellStart();
  439.         fontStyle("NavBarFont1");
  440.         printText("doclet.navClassUse");
  441.         fontEnd();
  442.         navCellEnd();
  443.     }
  444.                                 
  445.     /**
  446.      * Print link for previous file.
  447.      *
  448.      * @param prev File name for the prev link.
  449.      */
  450.     public void navLinkPrevious(String prev) {
  451.         String tag = getText("doclet.Prev");
  452.         if (prev != null) {
  453.             printHyperLink(prev, "", tag, true) ;
  454.         } else {
  455.             print(tag);
  456.         }
  457.     }
  458.  
  459.     /**
  460.      * Print the word "PREV" to indicate that no link is available.
  461.      */
  462.     protected void navLinkPrevious() {
  463.         navLinkPrevious(null);
  464.     }
  465.                                 
  466.     /**
  467.      * Print link for next file.
  468.      *
  469.      * @param next File name for the next link.
  470.      */
  471.     public void navLinkNext(String next) {
  472.         String tag = getText("doclet.Next");
  473.         if (next != null) {
  474.             printHyperLink(next, "", tag, true);
  475.         } else {
  476.             print(tag);
  477.         }
  478.     }
  479.  
  480.     /**
  481.      * Print the word "NEXT" to indicate that no link is available.
  482.      */
  483.     protected void navLinkNext() {
  484.         navLinkNext(null);
  485.     }
  486.                                 
  487.     /**
  488.      * Print "FRAMES" link, to switch to the frame version of the output.
  489.      * 
  490.      * @param link File to be linked, "index.html".
  491.      */
  492.     protected void navShowLists(String link) {
  493.         printBoldTargetHyperLink(link, "_top", getText("doclet.FRAMES"));
  494.     }
  495.                                 
  496.     /**
  497.      * Print "FRAMES" link, to switch to the frame version of the output.
  498.      */
  499.     protected void navShowLists() {
  500.         navShowLists(relativepath + "index.html");
  501.     }
  502.                                 
  503.     /**
  504.      * Print "NO FRAMES" link, to switch to the non-frame version of the output.
  505.      * 
  506.      * @param link File to be linked.
  507.      */
  508.     protected void navHideLists(String link) {
  509.         printBoldTargetHyperLink(link, "_top", getText("doclet.NO_FRAMES"));
  510.     }
  511.                                 
  512.     /**
  513.      * Print "NO FRAMES" link, to switch to the non-frame version of the output.
  514.      */
  515.     protected void navHideLists() {
  516.         navHideLists(filename);
  517.     }
  518.          
  519.     /**                       
  520.      * Print "Tree" link in the navigation bar. If there is only one package 
  521.      * specified on the command line, then the "Tree" link will be to the 
  522.      * only "package-tree.html" file otherwise it will be to the 
  523.      * "overview-tree.html" file.
  524.      */
  525.     protected void navLinkTree() { 
  526.         navCellStart();
  527.         PackageDoc[] packages = Standard.configuration().packages;
  528.         if (packages.length == 1) {
  529.             printHyperLink(pathString(packages[0], "package-tree.html"), "",
  530.                            getText("doclet.Tree"), true, "NavBarFont1");
  531.         } else {
  532.             printHyperLink(relativepath + "overview-tree.html", "",
  533.                            getText("doclet.Tree"), true, "NavBarFont1");
  534.         }
  535.         navCellEnd();
  536.     }
  537.  
  538.     /**
  539.      * Print "Tree" link to the "overview-tree.html" file.
  540.      */
  541.     protected void navLinkMainTree(String label) {
  542.         printHyperLink(relativepath + "overview-tree.html", label);
  543.     }
  544.                                 
  545.     /**
  546.      * Print the word "Class" in the navigation bar cell, to indicate that 
  547.      * class link is not available.
  548.      */
  549.     protected void navLinkClass() {
  550.         navCellStart();
  551.         fontStyle("NavBarFont1");
  552.         printText("doclet.Class");
  553.         fontEnd();
  554.         navCellEnd();
  555.     }
  556.                                 
  557.     /**
  558.      * Print "Deprecated" API link in the navigation bar.
  559.      */
  560.     protected void navLinkDeprecated() {
  561.         navCellStart();
  562.         printHyperLink(relativepath + "deprecated-list.html", "",
  563.                        getText("doclet.navDeprecated"), true, "NavBarFont1");
  564.         navCellEnd();
  565.     }
  566.                                                                 
  567.     /**
  568.      * Print link for generated index. If the user has used "-splitindex" 
  569.      * command line option, then link to file "index-files/index-1.html" is
  570.      * generated otherwise link to file "index-all.html" is generated.
  571.      */
  572.     protected void navLinkIndex() {
  573.         navCellStart();
  574.         printHyperLink(relativepath + 
  575.                        (Standard.configuration().splitindex?
  576.                             DirectoryManager.getPath("index-files") + 
  577.                             fileseparator: "") + 
  578.                        (Standard.configuration().splitindex?
  579.                             "index-1.html" : "index-all.html"), "", 
  580.                        getText("doclet.Index"), true, "NavBarFont1");
  581.         navCellEnd();
  582.     }
  583.  
  584.     /**
  585.      * Print help file link. If user has provided a help file, then generate a 
  586.      * link to the user given file, which is already copied to current or 
  587.      * destination directory.
  588.      */
  589.     protected void navLinkHelp() {
  590.         String helpfilenm = Standard.configuration().helpfile;
  591.         if (helpfilenm.equals("")) {
  592.             helpfilenm = "help-doc.html"; 
  593.         } else {
  594.             int lastsep;
  595.             if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) {
  596.                 helpfilenm = helpfilenm.substring(lastsep + 1);
  597.             }
  598.         } 
  599.         navCellStart();
  600.         printHyperLink(relativepath + helpfilenm, "", 
  601.                        getText("doclet.Help"), true, "NavBarFont1");
  602.         navCellEnd();
  603.     }
  604.  
  605.     /**
  606.      * Print the word "Detail" in the navigation bar. No link is available.
  607.      */
  608.     protected void navDetail() {
  609.         printText("doclet.Detail");
  610.     }
  611.  
  612.     /**
  613.      * Print the word "Summary" in the navigation bar. No link is available.
  614.      */                             
  615.     protected void navSummary() {
  616.         printText("doclet.Summary");
  617.     }
  618.    
  619.     /**                             
  620.      * Print the Html table tag for the index summary tables. The table tag
  621.      * printed is 
  622.      * <TABLE BORDER="1" CELLPADDING="3" "CELLSPACING="0" WIDTH="100%">
  623.      */
  624.     public void tableIndexSummary() {
  625.         println("\n<TABLE BORDER=\"1\" CELLPADDING=\"3\" " + 
  626.                 "CELLSPACING=\"0\" WIDTH=\"100%\">");
  627.     }
  628.  
  629.     /**                             
  630.      * Same as {@link #tableIndexSummary()}.
  631.      */
  632.     public void tableIndexDetail() {
  633.         println("\n<TABLE BORDER=\"1\" CELLPADDING=\"3\" " + 
  634.                 "CELLSPACING=\"0\" WIDTH=\"100%\">");
  635.     }
  636.  
  637.     /**
  638.      * Print Html tag for table elements. The tag printed is
  639.      * <TD ALIGN="right" VALIGN="top" WIDTH="1%">.
  640.      */
  641.     public void tdIndex() {
  642.         print("<TD ALIGN=\"right\" VALIGN=\"top\" WIDTH=\"1%\">");
  643.     }
  644.  
  645.     /**
  646.      * Prine table header information about color, column span and the font.
  647.      *
  648.      * @param color Background color.
  649.      * @param span  Column span.
  650.      */
  651.     public void tableHeaderStart(String color, int span) {
  652.         trBgcolorStyle(color, "TableHeadingColor");
  653.         tdColspan(span);
  654.         font("+2");
  655.     }
  656.  
  657.     /**
  658.      * Print table header for the inherited members summary tables. Print the
  659.      * background color information.
  660.      *
  661.      * @param color Background color.
  662.      */
  663.     public void tableInheritedHeaderStart(String color) {
  664.         trBgcolorStyle(color, "TableSubHeadingColor");
  665.         td();
  666.     }
  667.  
  668.     /**
  669.      * Print "Use" table header. Print the background color and the column span.
  670.      *
  671.      * @param color Background color.
  672.      */
  673.     public void tableUseInfoHeaderStart(String color) {
  674.         trBgcolorStyle(color, "TableSubHeadingColor");
  675.         tdColspan(2);
  676.     }
  677.     
  678.     /**
  679.      * Print table header with the background color with default column span 2.
  680.      *
  681.      * @param color Background color.
  682.      */
  683.     public void tableHeaderStart(String color) {
  684.         tableHeaderStart(color, 2);
  685.     }
  686.  
  687.     /**
  688.      * Print table header with the column span, with the default color #CCCCFF.
  689.      *
  690.      * @param span Column span.
  691.      */   
  692.     public void tableHeaderStart(int span) {
  693.         tableHeaderStart("#CCCCFF", span);
  694.     }
  695.   
  696.     /**
  697.      * Print table header with default column span 2 and default color #CCCCFF.
  698.      */       
  699.     public void tableHeaderStart() {
  700.         tableHeaderStart(2);
  701.     }
  702.  
  703.     /**
  704.      * Print table header end tags for font, column and row.
  705.      */   
  706.     public void tableHeaderEnd() {
  707.         fontEnd();
  708.         tdEnd();
  709.         trEnd();
  710.     }
  711.  
  712.     /**
  713.      * Print table header end tags in inherited tables for column and row.
  714.      */  
  715.     public void tableInheritedHeaderEnd() {
  716.         tdEnd();
  717.         trEnd();
  718.     }
  719.  
  720.     /**
  721.      * Print the summary table row cell attribute width.
  722.      *
  723.      * @param width Width of the table cell.
  724.      */
  725.     public void summaryRow(int width) {
  726.          if (width != 0) {
  727.              tdWidth(width + "%");
  728.          } else {
  729.              td();
  730.          }
  731.     } 
  732.  
  733.     /**
  734.      * Print the summary table row cell end tag.
  735.      */       
  736.     public void summaryRowEnd() {
  737.          tdEnd();
  738.     } 
  739.  
  740.     /**       
  741.      * Print the heading in Html <H2> format.
  742.      * 
  743.      * @param str The Header string.
  744.      */
  745.     public void printIndexHeading(String str) {
  746.         h2();
  747.         print(str);
  748.         h2End();
  749.     } 
  750.  
  751.     /**
  752.      * Print Html tag <FRAMESET=arg>.
  753.      * 
  754.      * @param arg Argument for the tag.
  755.      */
  756.     public void frameSet(String arg) {
  757.         println("<FRAMESET " + arg + ">");
  758.     }
  759.  
  760.     /**
  761.      * Print Html closing tag </FRAMESET>.
  762.      */
  763.     public void frameSetEnd() {
  764.         println("</FRAMESET>");
  765.     }
  766.  
  767.     /**
  768.      * Print Html tag <FRAME=arg>.
  769.      * 
  770.      * @param arg Argument for the tag.
  771.      */
  772.     public void frame(String arg) {
  773.         println("<FRAME " + arg + ">");
  774.     }
  775.  
  776.     /**
  777.      * Print Html closing tag </FRAME>.
  778.      */
  779.     public void frameEnd() {
  780.         println("</FRAME>");
  781.     }
  782.  
  783.     /**
  784.      * Return path to the class page for a classdoc. For example, the class 
  785.      * name is "java.lang.Object" and if the current file getting generated is
  786.      * "java/io/File.html", then the path string to the class, returned is 
  787.      * "../../java/lang.Object.html".
  788.      * 
  789.      * @param cd Class to which the path is requested.
  790.      */
  791.     protected String pathToClass(ClassDoc cd) {
  792.         return pathString(cd.containingPackage(), cd.name() + ".html");
  793.     }
  794.  
  795.     /**
  796.      * Return the path to the class page for a classdoc. Works same as 
  797.      * {@link #pathToClass(ClassDoc)}.
  798.      *
  799.      * @param cd   Class to which the path is requested.
  800.      * @param name Name of the file(doesn't include path).
  801.      */
  802.     protected String pathString(ClassDoc cd, String name) {
  803.         return pathString(cd.containingPackage(), name);
  804.     }
  805.  
  806.     /**
  807.      * Return path to the given file name in the given package. So if the name
  808.      * passed is "Object.html" and the name of the package is "java.lang", and
  809.      * if the relative path is "../.." then returned string will be
  810.      * "../../java/lang/Object.html"
  811.      *
  812.      * @param pd Package in which the file name is assumed to be.
  813.      * @param name File name, to which path string is.
  814.      */
  815.     protected String pathString(PackageDoc pd, String name) {
  816.         StringBuffer buf = new StringBuffer(relativepath);
  817.         buf.append(DirectoryManager.getPathToPackage(pd, name));
  818.         return buf.toString();
  819.     }
  820.  
  821.     /**
  822.      * Print link to the "pacakge-summary.html" file, depending upon the 
  823.      * package name.
  824.      */
  825.     public void printPackageLink(PackageDoc pkg) {
  826.         print(getPackageLink(pkg));
  827.     }
  828.  
  829.     public void printPackageLink(PackageDoc pkg, String linklabel) {
  830.         print(getPackageLink(pkg, linklabel));
  831.     }
  832.  
  833.     /**
  834.      * Get link for individual package file.
  835.      */
  836.     public String getPackageLink(PackageDoc pkg) {
  837.         return getPackageLink(pkg, pkg.name());
  838.     }
  839.  
  840.     public String getPackageLink(PackageDoc pkg, String linklabel) {
  841.         if (pkg.isIncluded()) { 
  842.             return getHyperLink(pathString(pkg, "package-summary.html"),
  843.                                 linklabel);
  844.         } else {
  845.             String crossPkgLink = getCrossPackageLink(pkg.name());
  846.             if (crossPkgLink != null) {
  847.                 return getHyperLink(crossPkgLink, linklabel);
  848.             } else {
  849.                 return linklabel;
  850.             }
  851.         }
  852.     }
  853.  
  854.     public String italicsClassName(ClassDoc cd, boolean qual) {
  855.         String name = (qual)? cd.qualifiedName(): cd.name();
  856.         return (cd.isInterface())?  italicsText(name): name;
  857.     }
  858.        
  859.     public void printClassLinkForSameDir(ClassDoc cd) {
  860.         if (cd.isIncluded()) {
  861.             printHyperLink(cd.name() + ".html", "", italicsClassName(cd, 
  862.                                                                      false));
  863.         } else {
  864.             print(italicsClassName(cd, true));
  865.         }
  866.     } 
  867.  
  868.     public void printClassLink(ClassDoc cd) {
  869.         print(getClassLink(cd, false));
  870.     }
  871.  
  872.     public String getClassLink(ClassDoc cd) {
  873.         return getClassLink(cd, false);
  874.     }
  875.  
  876.     public void printClassLink(ClassDoc cd, String label) {
  877.         print(getClassLink(cd, "", label, false));
  878.     }
  879.  
  880.     public String getClassLink(ClassDoc cd, String label) {
  881.         return getClassLink(cd, "", label, false);
  882.     }
  883.  
  884.     public void printClassLink(ClassDoc cd, String where, String label) {
  885.         print(getClassLink(cd, where, label, false));
  886.     }
  887.  
  888.     public void printClassLink(ClassDoc cd, String label, boolean bold) {
  889.         print(getClassLink(cd, "", label, bold));
  890.     }
  891.  
  892.     public void printClassLink(ClassDoc cd, String where, String label, 
  893.                                boolean bold, String color) {
  894.         print(getClassLink(cd, where, label, bold, color));
  895.     }
  896.  
  897.     public String getClassLink(ClassDoc cd, String where, String label) {
  898.         return getClassLink(cd, where, label, false);
  899.     }
  900.  
  901.     public void printClassLink(ClassDoc cd, boolean bold) {
  902.         print(getClassLink(cd, bold));
  903.     }
  904.  
  905.     public String getClassLink(ClassDoc cd, boolean bold) {
  906.         return getClassLink(cd, "", "", bold);
  907.     }
  908.  
  909.     public void printClassLink(ClassDoc cd, String where, 
  910.                                String label, boolean bold) {
  911.         print(getClassLink(cd, where, label, bold));
  912.     }
  913.  
  914.     public String getClassLink(ClassDoc cd, String where,
  915.                                String label, boolean bold, String color) {
  916.         boolean nameUnspecified = label.length() == 0;
  917.         if (nameUnspecified) {
  918.             label = cd.name();
  919.         }
  920.         displayLength += label.length();
  921.         if (cd.isIncluded()) {
  922.             String filename = pathToClass(cd);
  923.             return getHyperLink(filename, where, label, bold, color);
  924.         } else {
  925.             String crosslink = getCrossClassLink(cd);
  926.             if (crosslink != null) {
  927.                 return getHyperLink(crosslink, where, label, bold, color);
  928.             } else {
  929.                 if (nameUnspecified) {
  930.                     displayLength -= label.length();
  931.                     label = cd.qualifiedName();
  932.                     displayLength += label.length();
  933.                 }            
  934.                 return label;
  935.             }
  936.         }
  937.     }
  938.  
  939.     public String getClassLink(ClassDoc cd, String where,
  940.                                String label, boolean bold) {
  941.         return getClassLink(cd, where, label, bold, "");
  942.     }
  943.  
  944.     public String getCrossClassLink(ClassDoc cd) {
  945.         return getCrossLink(cd.containingPackage().name(), 
  946.                             cd.name() + ".html");
  947.     }
  948.  
  949.     public boolean isCrossClassIncluded(ClassDoc cd) {
  950.         if (cd.isIncluded()) {
  951.             return true;
  952.         }
  953.         return Extern.findPackage(cd.containingPackage().name()) != null; 
  954.     }
  955.  
  956.     public String getCrossPackageLink(String packagename) {
  957.         return getCrossLink(packagename, "package-summary.html");
  958.     }
  959.  
  960.     public String getCrossLink(String packagename, String link) {
  961.         Extern fnd = Extern.findPackage(packagename);
  962.         if (fnd != null) {
  963.             String externlink = fnd.path + link;
  964.             if (fnd.relative) {  // it's a relative path.
  965.                 return relativepath + externlink;
  966.             } else {  
  967.                 return externlink; 
  968.             }
  969.         }
  970.         return null;
  971.     }
  972.  
  973.     public void printQualifiedClassLink(ClassDoc cd) {
  974.         printClassLink(cd, "", cd.qualifiedName());
  975.     }
  976.  
  977.     public String getQualifiedClassLink(ClassDoc cd) {
  978.         return getClassLink(cd, "", cd.qualifiedName());
  979.     }
  980.  
  981.     /**
  982.      * Print Class link, with only class name as the link and prefixing
  983.      * plain package name.
  984.      */
  985.     public void printPreQualifiedClassLink(ClassDoc cd) {
  986.         print(getPreQualifiedClassLink(cd, false));
  987.     }
  988.  
  989.     public String getPreQualifiedClassLink(ClassDoc cd) {
  990.         return getPreQualifiedClassLink(cd, false);
  991.     }
  992.  
  993.     public String getPreQualifiedClassLink(ClassDoc cd, boolean bold) {
  994.         String classlink = getPkgName(cd);
  995.         classlink += getClassLink(cd, "", cd.name(), bold);
  996.         return classlink; 
  997.     }
  998.     
  999.     
  1000.     /**
  1001.      * Print Class link, with only class name as the bold link and prefixing
  1002.      * plain package name.
  1003.      */
  1004.     public void printPreQualifiedBoldClassLink(ClassDoc cd) {
  1005.         print(getPreQualifiedClassLink(cd, true));
  1006.     }
  1007.  
  1008.     public void printText(String key) {
  1009.         print(getText(key));
  1010.     }
  1011.  
  1012.     public void printText(String key, String a1) {
  1013.         print(getText(key, a1));
  1014.     }
  1015.  
  1016.     public void printText(String key, String a1, String a2) {
  1017.         print(getText(key, a1, a2));
  1018.     }
  1019.  
  1020.     public void boldText(String key) {
  1021.         bold(getText(key));
  1022.     }
  1023.  
  1024.     public void boldText(String key, String a1) {
  1025.         bold(getText(key, a1));
  1026.     }
  1027.  
  1028.     public void boldText(String key, String a1, String a2) {
  1029.         bold(getText(key, a1, a2));
  1030.     }
  1031.  
  1032.     public String getText(String key) {
  1033.         return Standard.configuration().standardmessage.getText(key);
  1034.     }
  1035.  
  1036.     public String getText(String key, String a1) {
  1037.         return Standard.configuration().standardmessage.getText(key, a1);
  1038.     }
  1039.  
  1040.     public String getText(String key, String a1, String a2) {
  1041.         return Standard.configuration().standardmessage.getText(key, a1, a2);
  1042.     }
  1043.  
  1044.     public String getText(String key, String a1, String a2, String a3) {
  1045.         return Standard.configuration().standardmessage.getText(key, a1, 
  1046.                                                                 a2, a3);
  1047.     }
  1048.  
  1049.     public void notice(String key, String a1) {
  1050.         Standard.configuration().standardmessage.notice(key, a1);
  1051.     }
  1052.  
  1053.     public void notice(String key, String a1, String a2) {
  1054.         Standard.configuration().standardmessage.notice(key, a1, a2);
  1055.     }
  1056.  
  1057.     public void warning(String key, String a1) {
  1058.         Standard.configuration().standardmessage.warning(key, a1);
  1059.     }
  1060.  
  1061.     public void error(String key, String a1) {
  1062.         Standard.configuration().standardmessage.notice(key, a1);
  1063.     }
  1064.  
  1065.     public void error(String key, String a1, String a2) {
  1066.         Standard.configuration().standardmessage.notice(key, a1, a2);
  1067.     }
  1068.  
  1069.     /**
  1070.      * Print link for any doc element.
  1071.      */
  1072.     public void printDocLink(Doc doc, String label, boolean bold) {
  1073.         print(getDocLink(doc, label, bold));
  1074.     }
  1075.  
  1076.     public String getDocLink(Doc doc, String label, boolean bold) {
  1077.         if (doc instanceof PackageDoc) {
  1078.             return getPackageLink((PackageDoc)doc, label);
  1079.         } else if (doc instanceof ClassDoc) {
  1080.             return getClassLink((ClassDoc)doc, "", label, bold);
  1081.         } else if (doc instanceof ExecutableMemberDoc) {
  1082.             ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
  1083.             return getClassLink(emd.containingClass(),  
  1084.                                 emd.name()+emd.signature(), label, bold);
  1085.         } else if (doc instanceof MemberDoc) {
  1086.             MemberDoc md = (MemberDoc)doc;
  1087.             return getClassLink(md.containingClass(), md.name(), label, bold);
  1088.         } else if (doc instanceof RootDoc) {
  1089.             return getHyperLink("overview-summary.html", label);
  1090.         } else {
  1091.             return label;
  1092.         }
  1093.     }
  1094.  
  1095.     public void printDocLink(Doc doc, String label) {
  1096.         printDocLink(doc, label, false);
  1097.     } 
  1098.  
  1099.     public String getDocLink(Doc doc, String label) {
  1100.         return getDocLink(doc, label, false);
  1101.     } 
  1102.  
  1103.    /**
  1104.      * Print the see tags information given the doc comment.
  1105.      *
  1106.      * @param doc Doc doc
  1107.      * @see com.sun.javadoc.Doc
  1108.      */
  1109.     public void printSeeTags(Doc doc) {
  1110.        SeeTag[] sees = doc.seeTags();
  1111.        if (sees.length > 0) {
  1112.             dt();
  1113.             boldText("doclet.See_Also");
  1114.             dd();
  1115.             for (int i = 0; i < sees.length; ++i) {
  1116.                 if (i > 0) {
  1117.                     println(", ");
  1118.                 }
  1119.                 printSeeTag(sees[i]);
  1120.             }
  1121.         }
  1122.         if (doc.isClass() && ((ClassDoc)doc).isSerializable()) {
  1123.             if (sees.length > 0) {
  1124.                 print(", ");
  1125.             } else {
  1126.                 dt();
  1127.                 boldText("doclet.See_Also");
  1128.                 dd();
  1129.             }   
  1130.             printHyperLink(relativepath + "serialized-form.html", 
  1131.                            ((ClassDoc)(doc)).qualifiedName(),
  1132.                            getText("doclet.Serialized_Form")); 
  1133.         }
  1134.     }
  1135.                
  1136.     public void printSeeTag(SeeTag see) {
  1137.         PackageDoc refPackage = see.referencedPackage();
  1138.         ClassDoc refClass = see.referencedClass();
  1139.         String refClassName = see.referencedClassName();
  1140.         String refPackName = refClassName;
  1141.         MemberDoc refMem = see.referencedMember();
  1142.         String refMemName = see.referencedMemberName();
  1143.         String label = see.label();
  1144.         String seetext = see.text();
  1145.         String text = getCode() + seetext + getCodeEnd();
  1146.         if (seetext.startsWith("<")) {
  1147.             print(seetext);
  1148.             return;
  1149.         }
  1150.         if (refClass == null) {
  1151.             if (refPackage != null && refPackage.isIncluded()) { 
  1152.                 printPackageLink(refPackage);
  1153.             } else {
  1154.                 // getCrossPackageLink for package
  1155.                 if (refPackName != null && refPackName.length() > 0) {
  1156.                     String crosslink = getCrossPackageLink(refPackName);
  1157.                     if (crosslink != null) {
  1158.                         printHyperLink(crosslink, "", refPackName, false);
  1159.                     } else {  
  1160.                         warning("doclet.see.class_or_package_not_found", 
  1161.                                                                    seetext);
  1162.                         print((label.length() == 0)? text: label);
  1163.                     }
  1164.                 } else {
  1165.                     error("doclet.see.malformed_tag", seetext);
  1166.                 }
  1167.             } 
  1168.         } else if (refMemName == null) {
  1169.             // class reference
  1170.             if (label.length() == 0) {
  1171.                 label = getCode() + refClass.name() + getCodeEnd();
  1172.                 printClassLink(refClass, label); 
  1173.             } else {
  1174.                 printClassLink(refClass, (label.length() == 0)? text: label);
  1175.             }
  1176.         } else if (refMem == null) {
  1177.             // can't find the member reference
  1178.             print((label.length() == 0)? text: label);
  1179.         } else {
  1180.             // member reference
  1181.             ClassDoc containing = refMem.containingClass();
  1182.             if (currentcd != containing) {
  1183.                 refMemName = containing.name() + "." + refMemName;
  1184.             }
  1185.             if (refMem instanceof ExecutableMemberDoc) {
  1186.                 if (refMemName.indexOf('(') < 0) {
  1187.                     refMemName += ((ExecutableMemberDoc)refMem).signature();
  1188.                 }
  1189.             } 
  1190.             text = getCode() + refMemName + getCodeEnd();
  1191.             printDocLink(refMem, (label.length() == 0)? text: label);
  1192.         }
  1193.     }  
  1194.  
  1195.     /**
  1196.      * Print tag information
  1197.      */
  1198.     public void generateTagInfo(Doc doc) {
  1199.         Tag[] sinces = doc.tags("since");
  1200.         Tag[] sees = doc.seeTags();
  1201.         Tag[] authors;
  1202.         Tag[] versions;
  1203.         if (configuration.showauthor) {
  1204.             authors = doc.tags("author");
  1205.         } else {
  1206.             authors = new Tag[0];
  1207.         }
  1208.         if (configuration.showversion) {
  1209.             versions = doc.tags("version");
  1210.         } else {
  1211.             versions = new Tag[0];
  1212.         }
  1213.         if (sinces.length > 0
  1214.             || sees.length > 0
  1215.             || authors.length > 0
  1216.             || versions.length > 0 
  1217.             || (doc.isClass() && ((ClassDoc)doc).isSerializable())) {
  1218.             dl();
  1219.             printSinceTag(doc);
  1220.             if (versions.length > 0) {
  1221.                 // There is going to be only one Version tag.
  1222.                 dt();
  1223.                 boldText("doclet.Version");
  1224.                 dd();
  1225.                 printInlineComment(versions[0]);
  1226.                 ddEnd();
  1227.             }
  1228.             if (authors.length > 0) {
  1229.                 dt();
  1230.                 boldText("doclet.Author");
  1231.                 dd();
  1232.                 for (int i = 0; i < authors.length; ++i) {
  1233.                     if (i > 0) {
  1234.                         print(", ");
  1235.                     } 
  1236.                     printInlineComment(authors[i]);
  1237.                 }
  1238.                 ddEnd();
  1239.             }
  1240.             printSeeTags(doc);
  1241.             dlEnd();
  1242.         }
  1243.     }
  1244.  
  1245.  
  1246.     public void printSinceTag(Doc doc) {
  1247.         Tag[] sinces = doc.tags("since");
  1248.         if (sinces.length > 0) {   // there is going to be only one since tag
  1249.             dt();
  1250.             boldText("doclet.Since");
  1251.             dd();
  1252.             printInlineComment(sinces[0]);
  1253.             ddEnd();
  1254.         }
  1255.     }       
  1256.  
  1257.     public void printInlineComment(Tag tag) {
  1258.         printCommentTags(tag.inlineTags(), false, false);
  1259.     }
  1260.  
  1261.     public void printInlineDeprecatedComment(Tag tag) {
  1262.         printCommentTags(tag.inlineTags(), true, false);
  1263.     }
  1264.     
  1265.     public void printSummaryComment(Doc doc) {
  1266.         printCommentTags(doc.firstSentenceTags(), false, true);
  1267.     }
  1268.     
  1269.     public void printSummaryDeprecatedComment(Doc doc) {
  1270.         printCommentTags(doc.firstSentenceTags(), true, true);
  1271.     }
  1272.     
  1273.     public void printSummaryDeprecatedComment(Tag tag) {
  1274.         printCommentTags(tag.firstSentenceTags(), true, true);
  1275.     }
  1276.     
  1277.     public void printInlineComment(Doc doc) {
  1278.         printCommentTags(doc.inlineTags(), false, false);
  1279.     }
  1280.     
  1281.     public void printInlineDeprecatedComment(Doc doc) {
  1282.         printCommentTags(doc.inlineTags(), true, false);
  1283.     }
  1284.     
  1285.     private void printCommentTags(Tag[] tags, boolean depr, boolean first) {
  1286.         if (depr) {
  1287.             italic();
  1288.         }
  1289.         for (int i = 0; i < tags.length; i++) {
  1290.             Tag tagelem = tags[i];
  1291.             if (tagelem instanceof SeeTag) {
  1292.                 printSeeTag((SeeTag)tagelem);
  1293.             } else {
  1294.                 String text = tagelem.text(); 
  1295.                 if (first) {
  1296.                     text = removeNonInlineTags(text);
  1297.                 }
  1298.                 print(text);
  1299.             }
  1300.         }
  1301.         if (depr) {
  1302.             italicEnd();
  1303.         }
  1304.         if (tags.length == 0) {
  1305.             space();
  1306.         }
  1307.     }
  1308.  
  1309.     public String removeNonInlineTags(String text) {
  1310.         if (text.indexOf('<') < 0) {
  1311.             return text;
  1312.         }
  1313.         String noninlinetags[] = { "<ul>", "</ul>", "<ol>", "</ol>", 
  1314.                                    "<dl>", "</dl>", "<table>", "</table>", 
  1315.                                    "<tr>", "</tr>", "<td>", "</td>", 
  1316.                                    "<th>", "</th>", "<p>", "</p>", 
  1317.                                    "<li>", "</li>", "<dd>", "</dd>", 
  1318.                                    "<dir>", "</dir>", "<dt>", "</dt>", 
  1319.                                    "<h1>", "</h1>", "<h2>", "</h2>", 
  1320.                                    "<h3>", "</h3>", "<h4>", "</h4>", 
  1321.                                    "<h5>", "</h5>", "<h6>", "</h6>", 
  1322.                                    "<pre>", "</pre>", "<menu>", "</menu>", 
  1323.                                    "<listing>", "</listing>", "<hr>", 
  1324.                                    "<blockquote>", "</blockquote>", 
  1325.                                    "<center>", "</center>",
  1326.                                    "<UL>", "</UL>", "<OL>", "</OL>", 
  1327.                                    "<DL>", "</DL>", "<TABLE>", "</TABLE>", 
  1328.                                    "<TR>", "</TR>", "<TD>", "</TD>", 
  1329.                                    "<TH>", "</TH>", "<P>", "</P>", 
  1330.                                    "<LI>", "</LI>", "<DD>", "</DD>", 
  1331.                                    "<DIR>", "</DIR>", "<DT>", "</DT>", 
  1332.                                    "<H1>", "</H1>", "<H2>", "</H2>", 
  1333.                                    "<H3>", "</H3>", "<H4>", "</H4>", 
  1334.                                    "<H5>", "</H5>", "<H6>", "</H6>", 
  1335.                                    "<PRE>", "</PRE>", "<MENU>", "</MENU>", 
  1336.                                    "<LISTING>", "</LISTING>", "<HR>", 
  1337.                                    "<BLOCKQUOTE>", "</BLOCKQUOTE>", 
  1338.                                    "<CENTER>", "</CENTER>" 
  1339.                                  };
  1340.         for (int i = 0; i < noninlinetags.length; i++) {
  1341.             text = replace(text, noninlinetags[i], ""); 
  1342.         }
  1343.         return text;
  1344.     }
  1345.  
  1346.     public String replace(String text, String tobe, String by) {
  1347.         while (true) {
  1348.             int startindex = text.indexOf(tobe);
  1349.             if (startindex < 0) {
  1350.                 return text;
  1351.             }
  1352.             int endindex = startindex + tobe.length();
  1353.             StringBuffer replaced = new StringBuffer();
  1354.             if (startindex > 0) {
  1355.                 replaced.append(text.substring(0, startindex));
  1356.             }
  1357.             replaced.append(by);
  1358.             if (text.length() > endindex) {
  1359.                 replaced.append(text.substring(endindex)); 
  1360.             }
  1361.             text = replaced.toString();
  1362.         }
  1363.     }
  1364.  
  1365.     public void printStyleSheetProperties() {
  1366.         String filename = Standard.configuration().stylesheetfile;
  1367.         if (filename.length() > 0) {
  1368.             File stylefile = new File(filename);
  1369.             String parent = stylefile.getParent();
  1370.             filename = (parent == null)? 
  1371.                             filename:
  1372.                             filename.substring(parent.length() + 1);
  1373.         } else {
  1374.             filename = "stylesheet.css";
  1375.         }
  1376.         filename = relativepath + filename;
  1377.         link("REL =\"stylesheet\" TYPE=\"text/css\" HREF=\"" +
  1378.               filename + "\" " + "TITLE=\"Style\"");
  1379.     }
  1380.  
  1381.     /**
  1382.      * According to the Java Language Specifications, all the outer classes
  1383.      * and static inner classes are core classes.
  1384.      */
  1385.     public boolean isCoreClass(ClassDoc cd) {
  1386.         return cd.containingClass() == null || cd.isStatic();
  1387.     }
  1388.  
  1389. }
  1390.