langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
changeset 14357 faf9cde2817b
parent 14266 69453558960d
child 14358 9eda9239cba0
equal deleted inserted replaced
14267:6321fbe0cf50 14357:faf9cde2817b
    53 public class HtmlDocletWriter extends HtmlDocWriter {
    53 public class HtmlDocletWriter extends HtmlDocWriter {
    54 
    54 
    55     /**
    55     /**
    56      * Relative path from the file getting generated to the destination
    56      * Relative path from the file getting generated to the destination
    57      * directory. For example, if the file getting generated is
    57      * directory. For example, if the file getting generated is
    58      * "java/lang/Object.html", then the relative path string is "../../".
    58      * "java/lang/Object.html", then the path to the root is "../..".
    59      * This string can be empty if the file getting generated is in
    59      * This string can be empty if the file getting generated is in
    60      * the destination directory.
    60      * the destination directory.
    61      */
    61      */
    62     public String relativePath = "";
    62     public final DocPath pathToRoot;
    63 
    63 
    64     /**
    64     /**
    65      * Same as relativepath, but normalized to never be empty or
    65      * Platform-independent path from the current or the
    66      * end with a slash.
       
    67      */
       
    68     public String relativepathNoSlash = "";
       
    69 
       
    70     /**
       
    71      * Platform-dependent directory path from the current or the
       
    72      * destination directory to the file getting generated.
    66      * destination directory to the file getting generated.
    73      * Used when creating the file.
    67      * Used when creating the file.
    74      * For example, if the file getting generated is
    68      */
    75      * "java/lang/Object.html", then the path string is "java/lang".
    69     public final DocPath path;
    76      */
       
    77     public String path = "";
       
    78 
    70 
    79     /**
    71     /**
    80      * Name of the file getting generated. If the file getting generated is
    72      * Name of the file getting generated. If the file getting generated is
    81      * "java/lang/Object.html", then the filename is "Object.html".
    73      * "java/lang/Object.html", then the filename is "Object.html".
    82      */
    74      */
    83     public String filename = "";
    75     public final DocPath filename;
    84 
    76 
    85     /**
    77     /**
    86      * The display length used for indentation while generating the class page.
    78      * The display length used for indentation while generating the class page.
    87      */
    79      */
    88     public int displayLength = 0;
    80     public int displayLength = 0;
    98     protected boolean printedAnnotationHeading = false;
    90     protected boolean printedAnnotationHeading = false;
    99 
    91 
   100     /**
    92     /**
   101      * Constructor to construct the HtmlStandardWriter object.
    93      * Constructor to construct the HtmlStandardWriter object.
   102      *
    94      *
   103      * @param filename File to be generated.
    95      * @param path File to be generated.
   104      */
    96      */
   105     public HtmlDocletWriter(ConfigurationImpl configuration,
    97     public HtmlDocletWriter(ConfigurationImpl configuration, DocPath path)
   106                               String filename) throws IOException {
    98             throws IOException {
   107         super(configuration, filename);
    99         super(configuration, path);
   108         this.configuration = configuration;
       
   109         this.filename = filename;
       
   110     }
       
   111 
       
   112     /**
       
   113      * Constructor to construct the HtmlStandardWriter object.
       
   114      *
       
   115      * @param path         Platform-dependent {@link #path} used when
       
   116      *                     creating file.
       
   117      * @param filename     Name of file to be generated.
       
   118      * @param relativePath Value for the variable {@link #relativePath}.
       
   119      */
       
   120     public HtmlDocletWriter(ConfigurationImpl configuration,
       
   121                               String path, String filename,
       
   122                               String relativePath) throws IOException {
       
   123         super(configuration, path, filename);
       
   124         this.configuration = configuration;
   100         this.configuration = configuration;
   125         this.path = path;
   101         this.path = path;
   126         this.relativePath = relativePath;
   102         this.pathToRoot = path.parent().invert();
   127         this.relativepathNoSlash =
   103         this.filename = path.basename();
   128             DirectoryManager.getPathNoTrailingSlash(this.relativePath);
       
   129         this.filename = filename;
       
   130     }
   104     }
   131 
   105 
   132     /**
   106     /**
   133      * Replace {@docRoot} tag used in options that accept HTML text, such
   107      * Replace {@docRoot} tag used in options that accept HTML text, such
   134      * as -header, -footer, -top and -bottom, and when converting a relative
   108      * as -header, -footer, -top and -bottom, and when converting a relative
   163         }
   137         }
   164         StringBuilder buf = new StringBuilder();
   138         StringBuilder buf = new StringBuilder();
   165         int previndex = 0;
   139         int previndex = 0;
   166         while (true) {
   140         while (true) {
   167             if (configuration.docrootparent.length() > 0) {
   141             if (configuration.docrootparent.length() > 0) {
       
   142                 final String docroot_parent = "{@docroot}/..";
   168                 // Search for lowercase version of {@docRoot}/..
   143                 // Search for lowercase version of {@docRoot}/..
   169                 index = lowerHtml.indexOf("{@docroot}/..", previndex);
   144                 index = lowerHtml.indexOf(docroot_parent, previndex);
   170                 // If next {@docRoot}/.. pattern not found, append rest of htmlstr and exit loop
   145                 // If next {@docRoot}/.. pattern not found, append rest of htmlstr and exit loop
   171                 if (index < 0) {
   146                 if (index < 0) {
   172                     buf.append(htmlstr.substring(previndex));
   147                     buf.append(htmlstr.substring(previndex));
   173                     break;
   148                     break;
   174                 }
   149                 }
   175                 // If next {@docroot}/.. pattern found, append htmlstr up to start of tag
   150                 // If next {@docroot}/.. pattern found, append htmlstr up to start of tag
   176                 buf.append(htmlstr.substring(previndex, index));
   151                 buf.append(htmlstr.substring(previndex, index));
   177                 previndex = index + 13;  // length for {@docroot}/.. string
   152                 previndex = index + docroot_parent.length();
   178                 // Insert docrootparent absolute path where {@docRoot}/.. was located
   153                 // Insert docrootparent absolute path where {@docRoot}/.. was located
   179 
   154 
   180                 buf.append(configuration.docrootparent);
   155                 buf.append(configuration.docrootparent);
   181                 // Append slash if next character is not a slash
   156                 // Append slash if next character is not a slash
   182                 if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
   157                 if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
   183                     buf.append(DirectoryManager.URL_FILE_SEPARATOR);
   158                     buf.append('/');
   184                 }
   159                 }
   185             } else {
   160             } else {
       
   161                 final String docroot = "{@docroot}";
   186                 // Search for lowercase version of {@docRoot}
   162                 // Search for lowercase version of {@docRoot}
   187                 index = lowerHtml.indexOf("{@docroot}", previndex);
   163                 index = lowerHtml.indexOf(docroot, previndex);
   188                 // If next {@docRoot} tag not found, append rest of htmlstr and exit loop
   164                 // If next {@docRoot} tag not found, append rest of htmlstr and exit loop
   189                 if (index < 0) {
   165                 if (index < 0) {
   190                     buf.append(htmlstr.substring(previndex));
   166                     buf.append(htmlstr.substring(previndex));
   191                     break;
   167                     break;
   192                 }
   168                 }
   193                 // If next {@docroot} tag found, append htmlstr up to start of tag
   169                 // If next {@docroot} tag found, append htmlstr up to start of tag
   194                 buf.append(htmlstr.substring(previndex, index));
   170                 buf.append(htmlstr.substring(previndex, index));
   195                 previndex = index + 10;  // length for {@docroot} string
   171                 previndex = index + docroot.length();
   196                 // Insert relative path where {@docRoot} was located
   172                 // Insert relative path where {@docRoot} was located
   197                 buf.append(relativepathNoSlash);
   173                 buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath());
   198                 // Append slash if next character is not a slash
   174                 // Append slash if next character is not a slash
   199                 if (relativepathNoSlash.length() > 0 && previndex < htmlstr.length() &&
   175                 if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') {
   200                         htmlstr.charAt(previndex) != '/') {
   176                     buf.append('/');
   201                     buf.append(DirectoryManager.URL_FILE_SEPARATOR);
       
   202                 }
   177                 }
   203             }
   178             }
   204         }
   179         }
   205         return buf.toString();
   180         return buf.toString();
   206     }
   181     }
   310      * @param label tag for the link
   285      * @param label tag for the link
   311      * @return a content for the target package link
   286      * @return a content for the target package link
   312      */
   287      */
   313     public Content getTargetPackageLink(PackageDoc pd, String target,
   288     public Content getTargetPackageLink(PackageDoc pd, String target,
   314             Content label) {
   289             Content label) {
   315         return getHyperLink(pathString(pd, "package-summary.html"), "", label, "", target);
   290         return getHyperLink(pathString(pd, DocPaths.PACKAGE_SUMMARY), "", label, "", target);
   316     }
   291     }
   317 
   292 
   318     /**
   293     /**
   319      * Generates the HTML document tree and prints it out.
   294      * Generates the HTML document tree and prints it out.
   320      *
   295      *
   537      * Get link to the "overview-summary.html" page.
   512      * Get link to the "overview-summary.html" page.
   538      *
   513      *
   539      * @return a content tree for the link
   514      * @return a content tree for the link
   540      */
   515      */
   541     protected Content getNavLinkContents() {
   516     protected Content getNavLinkContents() {
   542         Content linkContent = getHyperLink(relativePath +
   517         Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_SUMMARY),
   543                 "overview-summary.html", "", overviewLabel, "", "");
   518                 "", overviewLabel, "", "");
   544         Content li = HtmlTree.LI(linkContent);
   519         Content li = HtmlTree.LI(linkContent);
   545         return li;
   520         return li;
   546     }
   521     }
   547 
   522 
   548     /**
   523     /**
   582      * Get link for previous file.
   557      * Get link for previous file.
   583      *
   558      *
   584      * @param prev File name for the prev link
   559      * @param prev File name for the prev link
   585      * @return a content tree for the link
   560      * @return a content tree for the link
   586      */
   561      */
   587     public Content getNavLinkPrevious(String prev) {
   562     public Content getNavLinkPrevious(DocPath prev) {
   588         Content li;
   563         Content li;
   589         if (prev != null) {
   564         if (prev != null) {
   590             li = HtmlTree.LI(getHyperLink(prev, "", prevLabel, "", ""));
   565             li = HtmlTree.LI(getHyperLink(prev, "", prevLabel, "", ""));
   591         }
   566         }
   592         else
   567         else
   599      * without linking it anywhere.
   574      * without linking it anywhere.
   600      *
   575      *
   601      * @param next File name for the next link
   576      * @param next File name for the next link
   602      * @return a content tree for the link
   577      * @return a content tree for the link
   603      */
   578      */
   604     public Content getNavLinkNext(String next) {
   579     public Content getNavLinkNext(DocPath next) {
   605         Content li;
   580         Content li;
   606         if (next != null) {
   581         if (next != null) {
   607             li = HtmlTree.LI(getHyperLink(next, "", nextLabel, "", ""));
   582             li = HtmlTree.LI(getHyperLink(next, "", nextLabel, "", ""));
   608         }
   583         }
   609         else
   584         else
   615      * Get "FRAMES" link, to switch to the frame version of the output.
   590      * Get "FRAMES" link, to switch to the frame version of the output.
   616      *
   591      *
   617      * @param link File to be linked, "index.html"
   592      * @param link File to be linked, "index.html"
   618      * @return a content tree for the link
   593      * @return a content tree for the link
   619      */
   594      */
   620     protected Content getNavShowLists(String link) {
   595     protected Content getNavShowLists(DocPath link) {
   621         Content framesContent = getHyperLink(link + "?" + path +
   596         Content framesContent = getHyperLink(link.getPath() + "?" + path.getPath(),
   622                 filename, "", framesLabel, "", "_top");
   597                 "", framesLabel, "", "_top");
   623         Content li = HtmlTree.LI(framesContent);
   598         Content li = HtmlTree.LI(framesContent);
   624         return li;
   599         return li;
   625     }
   600     }
   626 
   601 
   627     /**
   602     /**
   628      * Get "FRAMES" link, to switch to the frame version of the output.
   603      * Get "FRAMES" link, to switch to the frame version of the output.
   629      *
   604      *
   630      * @return a content tree for the link
   605      * @return a content tree for the link
   631      */
   606      */
   632     protected Content getNavShowLists() {
   607     protected Content getNavShowLists() {
   633         return getNavShowLists(relativePath + "index.html");
   608         return getNavShowLists(pathToRoot.resolve(DocPaths.INDEX));
   634     }
   609     }
   635 
   610 
   636     /**
   611     /**
   637      * Get "NO FRAMES" link, to switch to the non-frame version of the output.
   612      * Get "NO FRAMES" link, to switch to the non-frame version of the output.
   638      *
   613      *
   639      * @param link File to be linked
   614      * @param link File to be linked
   640      * @return a content tree for the link
   615      * @return a content tree for the link
   641      */
   616      */
   642     protected Content getNavHideLists(String link) {
   617     protected Content getNavHideLists(DocPath link) {
   643         Content noFramesContent = getHyperLink(link, "", noframesLabel, "", "_top");
   618         Content noFramesContent = getHyperLink(link, "", noframesLabel, "", "_top");
   644         Content li = HtmlTree.LI(noFramesContent);
   619         Content li = HtmlTree.LI(noFramesContent);
   645         return li;
   620         return li;
   646     }
   621     }
   647 
   622 
   656     protected Content getNavLinkTree() {
   631     protected Content getNavLinkTree() {
   657         Content treeLinkContent;
   632         Content treeLinkContent;
   658         PackageDoc[] packages = configuration.root.specifiedPackages();
   633         PackageDoc[] packages = configuration.root.specifiedPackages();
   659         if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) {
   634         if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) {
   660             treeLinkContent = getHyperLink(pathString(packages[0],
   635             treeLinkContent = getHyperLink(pathString(packages[0],
   661                     "package-tree.html"), "", treeLabel,
   636                     DocPaths.PACKAGE_TREE), "", treeLabel,
   662                     "", "");
   637                     "", "");
   663         } else {
   638         } else {
   664             treeLinkContent = getHyperLink(relativePath + "overview-tree.html",
   639             treeLinkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
   665                     "", treeLabel, "", "");
   640                     "", treeLabel, "", "");
   666         }
   641         }
   667         Content li = HtmlTree.LI(treeLinkContent);
   642         Content li = HtmlTree.LI(treeLinkContent);
   668         return li;
   643         return li;
   669     }
   644     }
   673      *
   648      *
   674      * @param label the label for the link
   649      * @param label the label for the link
   675      * @return a content tree for the link
   650      * @return a content tree for the link
   676      */
   651      */
   677     protected Content getNavLinkMainTree(String label) {
   652     protected Content getNavLinkMainTree(String label) {
   678         Content mainTreeContent = getHyperLink(relativePath + "overview-tree.html",
   653         Content mainTreeContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
   679                 new StringContent(label));
   654                 new StringContent(label));
   680         Content li = HtmlTree.LI(mainTreeContent);
   655         Content li = HtmlTree.LI(mainTreeContent);
   681         return li;
   656         return li;
   682     }
   657     }
   683 
   658 
   695      * Get "Deprecated" API link in the navigation bar.
   670      * Get "Deprecated" API link in the navigation bar.
   696      *
   671      *
   697      * @return a content tree for the link
   672      * @return a content tree for the link
   698      */
   673      */
   699     protected Content getNavLinkDeprecated() {
   674     protected Content getNavLinkDeprecated() {
   700         Content linkContent = getHyperLink(relativePath +
   675         Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
   701                 "deprecated-list.html", "", deprecatedLabel, "", "");
   676                 "", deprecatedLabel, "", "");
   702         Content li = HtmlTree.LI(linkContent);
   677         Content li = HtmlTree.LI(linkContent);
   703         return li;
   678         return li;
   704     }
   679     }
   705 
   680 
   706     /**
   681     /**
   709      * generated otherwise link to file "index-all.html" is generated.
   684      * generated otherwise link to file "index-all.html" is generated.
   710      *
   685      *
   711      * @return a content tree for the link
   686      * @return a content tree for the link
   712      */
   687      */
   713     protected Content getNavLinkClassIndex() {
   688     protected Content getNavLinkClassIndex() {
   714         Content allClassesContent = getHyperLink(relativePath +
   689         Content allClassesContent = getHyperLink(pathToRoot.resolve(
   715                 AllClassesFrameWriter.OUTPUT_FILE_NAME_NOFRAMES, "",
   690                 DocPaths.ALLCLASSES_NOFRAME), "",
   716                 allclassesLabel, "", "");
   691                 allclassesLabel, "", "");
   717         Content li = HtmlTree.LI(allClassesContent);
   692         Content li = HtmlTree.LI(allClassesContent);
   718         return li;
   693         return li;
   719     }
   694     }
   720 
   695 
   722      * Get link for generated class index.
   697      * Get link for generated class index.
   723      *
   698      *
   724      * @return a content tree for the link
   699      * @return a content tree for the link
   725      */
   700      */
   726     protected Content getNavLinkIndex() {
   701     protected Content getNavLinkIndex() {
   727         Content linkContent = getHyperLink(relativePath +(configuration.splitindex?
   702         Content linkContent = getHyperLink(pathToRoot.resolve(
   728             DirectoryManager.getPath("index-files") + fileseparator: "") +
   703                 (configuration.splitindex
   729             (configuration.splitindex?"index-1.html" : "index-all.html"), "",
   704                     ? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
       
   705                     : DocPaths.INDEX_ALL)), "",
   730             indexLabel, "", "");
   706             indexLabel, "", "");
   731         Content li = HtmlTree.LI(linkContent);
   707         Content li = HtmlTree.LI(linkContent);
   732         return li;
   708         return li;
   733     }
   709     }
   734 
   710 
   738      * destination directory.
   714      * destination directory.
   739      *
   715      *
   740      * @return a content tree for the link
   716      * @return a content tree for the link
   741      */
   717      */
   742     protected Content getNavLinkHelp() {
   718     protected Content getNavLinkHelp() {
   743         String helpfilenm = configuration.helpfile;
   719         String helpfile = configuration.helpfile;
   744         if (helpfilenm.equals("")) {
   720         DocPath helpfilenm;
   745             helpfilenm = "help-doc.html";
   721         if (helpfile.isEmpty()) {
       
   722             helpfilenm = DocPaths.HELP_DOC;
   746         } else {
   723         } else {
   747             int lastsep;
   724             helpfilenm = DocPath.create(new File(helpfile).getName());
   748             if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) {
   725         }
   749                 helpfilenm = helpfilenm.substring(lastsep + 1);
   726         Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm), "",
   750             }
       
   751         }
       
   752         Content linkContent = getHyperLink(relativePath + helpfilenm, "",
       
   753                 helpLabel, "", "");
   727                 helpLabel, "", "");
   754         Content li = HtmlTree.LI(linkContent);
   728         Content li = HtmlTree.LI(linkContent);
   755         return li;
   729         return li;
   756     }
   730     }
   757 
   731 
   882             contentTree.addContent(ul);
   856             contentTree.addContent(ul);
   883         }
   857         }
   884     }
   858     }
   885 
   859 
   886     /**
   860     /**
   887      * Return path to the class page for a classdoc. For example, the class
       
   888      * name is "java.lang.Object" and if the current file getting generated is
       
   889      * "java/io/File.html", then the path string to the class, returned is
       
   890      * "../../java/lang.Object.html".
       
   891      *
       
   892      * @param cd Class to which the path is requested.
       
   893      */
       
   894     protected String pathToClass(ClassDoc cd) {
       
   895         return pathString(cd.containingPackage(), cd.name() + ".html");
       
   896     }
       
   897 
       
   898     /**
       
   899      * Return the path to the class page for a classdoc. Works same as
   861      * Return the path to the class page for a classdoc. Works same as
   900      * {@link #pathToClass(ClassDoc)}.
   862      * {@link #pathToClass(ClassDoc)}.
   901      *
   863      *
   902      * @param cd   Class to which the path is requested.
   864      * @param cd   Class to which the path is requested.
   903      * @param name Name of the file(doesn't include path).
   865      * @param name Name of the file(doesn't include path).
   904      */
   866      */
   905     protected String pathString(ClassDoc cd, String name) {
   867     protected DocPath pathString(ClassDoc cd, DocPath name) {
   906         return pathString(cd.containingPackage(), name);
   868         return pathString(cd.containingPackage(), name);
   907     }
   869     }
   908 
   870 
   909     /**
   871     /**
   910      * Return path to the given file name in the given package. So if the name
   872      * Return path to the given file name in the given package. So if the name
   913      * "../../java/lang/Object.html"
   875      * "../../java/lang/Object.html"
   914      *
   876      *
   915      * @param pd Package in which the file name is assumed to be.
   877      * @param pd Package in which the file name is assumed to be.
   916      * @param name File name, to which path string is.
   878      * @param name File name, to which path string is.
   917      */
   879      */
   918     protected String pathString(PackageDoc pd, String name) {
   880     protected DocPath pathString(PackageDoc pd, DocPath name) {
   919         StringBuilder buf = new StringBuilder(relativePath);
   881         return pathToRoot.resolve(DocPath.forPackage(pd).resolve(name));
   920         buf.append(DirectoryManager.getPathToPackage(pd, name));
       
   921         return buf.toString();
       
   922     }
   882     }
   923 
   883 
   924     /**
   884     /**
   925      * Return the link to the given package.
   885      * Return the link to the given package.
   926      *
   886      *
   954                     break;
   914                     break;
   955                 }
   915                 }
   956             }
   916             }
   957         }
   917         }
   958         if (included || pkg == null) {
   918         if (included || pkg == null) {
   959             return getHyperLinkString(pathString(pkg, "package-summary.html"),
   919             return getHyperLinkString(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
   960                                 "", label, isStrong, style);
   920                                 "", label, isStrong, style);
   961         } else {
   921         } else {
   962             String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
   922             String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
   963             if (crossPkgLink != null) {
   923             if (crossPkgLink != null) {
   964                 return getHyperLinkString(crossPkgLink, "", label, isStrong, style);
   924                 return getHyperLinkString(/*TEMP*/ DocPath.create(crossPkgLink), "", label, isStrong, style);
   965             } else {
   925             } else {
   966                 return label;
   926                 return label;
   967             }
   927             }
   968         }
   928         }
   969     }
   929     }
   985                     break;
   945                     break;
   986                 }
   946                 }
   987             }
   947             }
   988         }
   948         }
   989         if (included || pkg == null) {
   949         if (included || pkg == null) {
   990             return getHyperLink(pathString(pkg, "package-summary.html"),
   950             return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
   991                                 "", label);
   951                                 "", label);
   992         } else {
   952         } else {
   993             String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
   953             String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg));
   994             if (crossPkgLink != null) {
   954             if (crossPkgLink != null) {
   995                 return getHyperLink(crossPkgLink, "", label);
   955                 return getHyperLink(/*TEMP*/ DocPath.create(crossPkgLink), "", label);
   996             } else {
   956             } else {
   997                 return label;
   957                 return label;
   998             }
   958             }
   999         }
   959         }
  1000     }
   960     }
  1018         ClassDoc cd = doc.containingClass();
   978         ClassDoc cd = doc.containingClass();
  1019         if (cd == null) {
   979         if (cd == null) {
  1020             //d must be a class doc since in has no containing class.
   980             //d must be a class doc since in has no containing class.
  1021             cd = (ClassDoc) doc;
   981             cd = (ClassDoc) doc;
  1022         }
   982         }
  1023         String href = relativePath + DocletConstants.SOURCE_OUTPUT_DIR_NAME
   983         DocPath href = pathToRoot
  1024                 + DirectoryManager.getDirectoryPath(cd.containingPackage())
   984                 .resolve(DocPaths.SOURCE_OUTPUT)
  1025                 + cd.name() + ".html#" + SourceToHTMLConverter.getAnchorName(doc);
   985                 .resolve(DocPath.forClass(cd));
  1026         Content linkContent = getHyperLink(href, "", label, "", "");
   986         Content linkContent = getHyperLink(href, SourceToHTMLConverter.getAnchorName(doc), label, "", "");
  1027         htmltree.addContent(linkContent);
   987         htmltree.addContent(linkContent);
  1028     }
   988     }
  1029 
   989 
  1030     /**
   990     /**
  1031      * Return the link to the given class.
   991      * Return the link to the given class.
  1083                 //class (assuming that it exists).  This is definitely a limitation of
  1043                 //class (assuming that it exists).  This is definitely a limitation of
  1084                 //the -link option.  There are ways to determine if an external package
  1044                 //the -link option.  There are ways to determine if an external package
  1085                 //exists, but no way to determine if the external class exists.  We just
  1045                 //exists, but no way to determine if the external class exists.  We just
  1086                 //have to assume that it does.
  1046                 //have to assume that it does.
  1087                 return getHyperLinkString(
  1047                 return getHyperLinkString(
  1088                     configuration.extern.getExternalLink(packageName, relativePath,
  1048                     configuration.extern.getExternalLink(packageName, pathToRoot,
  1089                                 className + ".html?is-external=true"),
  1049                                 className + ".html?is-external=true"),
  1090                     refMemName == null ? "" : refMemName,
  1050                     refMemName == null ? "" : refMemName,
  1091                     label == null || label.length() == 0 ? defaultLabel : label,
  1051                     label == null || label.length() == 0 ? defaultLabel : label,
  1092                     strong, style,
  1052                     strong, style,
  1093                     configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
  1053                     configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
  1103         }
  1063         }
  1104         return configuration.extern.isExternal(cd);
  1064         return configuration.extern.isExternal(cd);
  1105     }
  1065     }
  1106 
  1066 
  1107     public String getCrossPackageLink(String pkgName) {
  1067     public String getCrossPackageLink(String pkgName) {
  1108         return configuration.extern.getExternalLink(pkgName, relativePath,
  1068         return configuration.extern.getExternalLink(pkgName, pathToRoot,
  1109             "package-summary.html?is-external=true");
  1069             "package-summary.html?is-external=true");
  1110     }
  1070     }
  1111 
  1071 
  1112     /**
  1072     /**
  1113      * Get the class link.
  1073      * Get the class link.
  1319             } else {
  1279             } else {
  1320                 //@see is not referencing an included class or package.  Check for cross links.
  1280                 //@see is not referencing an included class or package.  Check for cross links.
  1321                 String classCrossLink, packageCrossLink = getCrossPackageLink(refClassName);
  1281                 String classCrossLink, packageCrossLink = getCrossPackageLink(refClassName);
  1322                 if (packageCrossLink != null) {
  1282                 if (packageCrossLink != null) {
  1323                     //Package cross link found
  1283                     //Package cross link found
  1324                     return getHyperLinkString(packageCrossLink, "",
  1284                     return getHyperLinkString(/*TEMP*/ DocPath.create(packageCrossLink), "",
  1325                         (label.isEmpty() ? text : label), false);
  1285                         (label.isEmpty() ? text : label), false);
  1326                 } else if ((classCrossLink = getCrossClassLink(refClassName,
  1286                 } else if ((classCrossLink = getCrossClassLink(refClassName,
  1327                         refMemName, label, false, "", !plain)) != null) {
  1287                         refMemName, label, false, "", !plain)) != null) {
  1328                     //Class cross link found (possibly to a member in the class)
  1288                     //Class cross link found (possibly to a member in the class)
  1329                     return classCrossLink;
  1289                     return classCrossLink;
  1448      * Adds the comment tags.
  1408      * Adds the comment tags.
  1449      *
  1409      *
  1450      * @param doc the doc for which the comment tags will be generated
  1410      * @param doc the doc for which the comment tags will be generated
  1451      * @param tags the first sentence tags for the doc
  1411      * @param tags the first sentence tags for the doc
  1452      * @param depr true if it is deprecated
  1412      * @param depr true if it is deprecated
  1453      * @param first true if the first sentenge tags should be added
  1413      * @param first true if the first sentence tags should be added
  1454      * @param htmltree the documentation tree to which the comment tags will be added
  1414      * @param htmltree the documentation tree to which the comment tags will be added
  1455      */
  1415      */
  1456     private void addCommentTags(Doc doc, Tag[] tags, boolean depr,
  1416     private void addCommentTags(Doc doc, Tag[] tags, boolean depr,
  1457             boolean first, Content htmltree) {
  1417             boolean first, Content htmltree) {
  1458         if(configuration.nocomment){
  1418         if(configuration.nocomment){
  1559                 this instanceof PackageSummaryWriter;
  1519                 this instanceof PackageSummaryWriter;
  1560     }
  1520     }
  1561 
  1521 
  1562     /**
  1522     /**
  1563      * Suppose a piece of documentation has a relative link.  When you copy
  1523      * Suppose a piece of documentation has a relative link.  When you copy
  1564      * that documetation to another place such as the index or class-use page,
  1524      * that documentation to another place such as the index or class-use page,
  1565      * that relative link will no longer work.  We should redirect those links
  1525      * that relative link will no longer work.  We should redirect those links
  1566      * so that they will work again.
  1526      * so that they will work again.
  1567      * <p>
  1527      * <p>
  1568      * Here is the algorithm used to fix the link:
  1528      * Here is the algorithm used to fix the link:
  1569      * <p>
  1529      * <p>
  1585     private String redirectRelativeLinks(Doc doc, String text) {
  1545     private String redirectRelativeLinks(Doc doc, String text) {
  1586         if (doc == null || shouldNotRedirectRelativeLinks()) {
  1546         if (doc == null || shouldNotRedirectRelativeLinks()) {
  1587             return text;
  1547             return text;
  1588         }
  1548         }
  1589 
  1549 
  1590         String redirectPathFromRoot;
  1550         DocPath redirectPathFromRoot;
  1591         if (doc instanceof ClassDoc) {
  1551         if (doc instanceof ClassDoc) {
  1592             redirectPathFromRoot = DirectoryManager.getDirectoryPath(((ClassDoc) doc).containingPackage());
  1552             redirectPathFromRoot = DocPath.forPackage(((ClassDoc) doc).containingPackage());
  1593         } else if (doc instanceof MemberDoc) {
  1553         } else if (doc instanceof MemberDoc) {
  1594             redirectPathFromRoot = DirectoryManager.getDirectoryPath(((MemberDoc) doc).containingPackage());
  1554             redirectPathFromRoot = DocPath.forPackage(((MemberDoc) doc).containingPackage());
  1595         } else if (doc instanceof PackageDoc) {
  1555         } else if (doc instanceof PackageDoc) {
  1596             redirectPathFromRoot = DirectoryManager.getDirectoryPath((PackageDoc) doc);
  1556             redirectPathFromRoot = DocPath.forPackage((PackageDoc) doc);
  1597         } else {
  1557         } else {
  1598             return text;
  1558             return text;
  1599         }
       
  1600 
       
  1601         if (! redirectPathFromRoot.endsWith(DirectoryManager.URL_FILE_SEPARATOR)) {
       
  1602             redirectPathFromRoot += DirectoryManager.URL_FILE_SEPARATOR;
       
  1603         }
  1559         }
  1604 
  1560 
  1605         //Redirect all relative links.
  1561         //Redirect all relative links.
  1606         int end, begin = text.toLowerCase().indexOf("<a");
  1562         int end, begin = text.toLowerCase().indexOf("<a");
  1607         if(begin >= 0){
  1563         if(begin >= 0){
  1625                 if (end == -1) {
  1581                 if (end == -1) {
  1626                     //Break without warning.  This <a> tag is not necessarily malformed.  The text
  1582                     //Break without warning.  This <a> tag is not necessarily malformed.  The text
  1627                     //might be missing '>' character because the href has an inline tag.
  1583                     //might be missing '>' character because the href has an inline tag.
  1628                     break;
  1584                     break;
  1629                 }
  1585                 }
  1630                 if(textBuff.substring(begin, end).indexOf("\"") != -1){
  1586                 if (textBuff.substring(begin, end).indexOf("\"") != -1){
  1631                     begin = textBuff.indexOf("\"", begin) + 1;
  1587                     begin = textBuff.indexOf("\"", begin) + 1;
  1632                     end = textBuff.indexOf("\"", begin +1);
  1588                     end = textBuff.indexOf("\"", begin +1);
  1633                     if(begin == 0 || end == -1){
  1589                     if (begin == 0 || end == -1){
  1634                         //Link is missing a quote.
  1590                         //Link is missing a quote.
  1635                         break;
  1591                         break;
  1636                     }
  1592                     }
  1637                 }
  1593                 }
  1638                 String relativeLink = textBuff.substring(begin, end);
  1594                 String relativeLink = textBuff.substring(begin, end);
  1639                 if(!(relativeLink.toLowerCase().startsWith("mailto:") ||
  1595                 if (!(relativeLink.toLowerCase().startsWith("mailto:") ||
  1640                      relativeLink.toLowerCase().startsWith("http:") ||
  1596                         relativeLink.toLowerCase().startsWith("http:") ||
  1641                      relativeLink.toLowerCase().startsWith("https:") ||
  1597                         relativeLink.toLowerCase().startsWith("https:") ||
  1642                      relativeLink.toLowerCase().startsWith("file:"))){
  1598                         relativeLink.toLowerCase().startsWith("file:"))) {
  1643                      relativeLink = "{@"+(new DocRootTaglet()).getName() + "}"
  1599                     relativeLink = "{@"+(new DocRootTaglet()).getName() + "}/"
  1644                         + redirectPathFromRoot
  1600                         + redirectPathFromRoot.resolve(relativeLink).getPath();
  1645                         + relativeLink;
       
  1646                     textBuff.replace(begin, end, relativeLink);
  1601                     textBuff.replace(begin, end, relativeLink);
  1647                 }
  1602                 }
  1648                 begin = textBuff.toString().toLowerCase().indexOf("<a", begin + 1);
  1603                 begin = textBuff.toString().toLowerCase().indexOf("<a", begin + 1);
  1649             }
  1604             }
  1650             return textBuff.toString();
  1605             return textBuff.toString();
  1713      *
  1668      *
  1714      * @return an HtmlTree for the lINK tag which provides the stylesheet location
  1669      * @return an HtmlTree for the lINK tag which provides the stylesheet location
  1715      */
  1670      */
  1716     public HtmlTree getStyleSheetProperties() {
  1671     public HtmlTree getStyleSheetProperties() {
  1717         String filename = configuration.stylesheetfile;
  1672         String filename = configuration.stylesheetfile;
       
  1673         DocPath stylesheet;
  1718         if (filename.length() > 0) {
  1674         if (filename.length() > 0) {
  1719             File stylefile = new File(filename);
  1675             stylesheet = DocPath.create(new File(filename).getName());
  1720             String parent = stylefile.getParent();
       
  1721             filename = (parent == null)?
       
  1722                 filename:
       
  1723                 filename.substring(parent.length() + 1);
       
  1724         } else {
  1676         } else {
  1725             filename = "stylesheet.css";
  1677             stylesheet = DocPaths.STYLESHEET;
  1726         }
  1678         }
  1727         filename = relativePath + filename;
  1679         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
  1728         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", filename, "Style");
  1680                 pathToRoot.resolve(stylesheet).getPath(),
       
  1681                 "Style");
  1729         return link;
  1682         return link;
  1730     }
  1683     }
  1731 
  1684 
  1732     /**
  1685     /**
  1733      * According to
  1686      * According to