duke@1: /* jjg@1326: * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package com.sun.tools.doclets.formats.html; duke@1: duke@1: import java.io.*; duke@1: import java.text.SimpleDateFormat; duke@1: import java.util.*; duke@1: bpatel@233: import com.sun.javadoc.*; bpatel@233: import com.sun.tools.doclets.formats.html.markup.*; bpatel@233: import com.sun.tools.doclets.internal.toolkit.*; bpatel@233: import com.sun.tools.doclets.internal.toolkit.util.*; bpatel@233: import com.sun.tools.doclets.internal.toolkit.taglets.*; duke@1: duke@1: /** duke@1: * Class for the Html Format Code Generation specific to JavaDoc. duke@1: * This Class contains methods related to the Html Code Generation which duke@1: * are used extensively while generating the entire documentation. duke@1: * duke@1: * @since 1.2 duke@1: * @author Atul M Dambalkar duke@1: * @author Robert Field bpatel@233: * @author Bhavesh Patel (Modified) duke@1: */ duke@1: public class HtmlDocletWriter extends HtmlDocWriter { duke@1: duke@1: /** duke@1: * Relative path from the file getting generated to the destination duke@1: * directory. For example, if the file getting generated is duke@1: * "java/lang/Object.html", then the relative path string is "../../". duke@1: * This string can be empty if the file getting generated is in duke@1: * the destination directory. duke@1: */ duke@1: public String relativePath = ""; duke@1: duke@1: /** duke@1: * Same as relativepath, but normalized to never be empty or duke@1: * end with a slash. duke@1: */ duke@1: public String relativepathNoSlash = ""; duke@1: duke@1: /** duke@1: * Platform-dependent directory path from the current or the duke@1: * destination directory to the file getting generated. duke@1: * Used when creating the file. duke@1: * For example, if the file getting generated is duke@1: * "java/lang/Object.html", then the path string is "java/lang". duke@1: */ duke@1: public String path = ""; duke@1: duke@1: /** duke@1: * Name of the file getting generated. If the file getting generated is duke@1: * "java/lang/Object.html", then the filename is "Object.html". duke@1: */ duke@1: public String filename = ""; duke@1: duke@1: /** duke@1: * The display length used for indentation while generating the class page. duke@1: */ duke@1: public int displayLength = 0; duke@1: duke@1: /** duke@1: * The global configuration information for this run. duke@1: */ duke@1: public ConfigurationImpl configuration; duke@1: duke@1: /** bpatel@766: * To check whether annotation heading is printed or not. bpatel@766: */ bpatel@766: protected boolean printedAnnotationHeading = false; bpatel@766: bpatel@766: /** duke@1: * Constructor to construct the HtmlStandardWriter object. duke@1: * duke@1: * @param filename File to be generated. duke@1: */ duke@1: public HtmlDocletWriter(ConfigurationImpl configuration, duke@1: String filename) throws IOException { duke@1: super(configuration, filename); duke@1: this.configuration = configuration; duke@1: this.filename = filename; duke@1: } duke@1: duke@1: /** duke@1: * Constructor to construct the HtmlStandardWriter object. duke@1: * duke@1: * @param path Platform-dependent {@link #path} used when duke@1: * creating file. duke@1: * @param filename Name of file to be generated. duke@1: * @param relativePath Value for the variable {@link #relativePath}. duke@1: */ duke@1: public HtmlDocletWriter(ConfigurationImpl configuration, duke@1: String path, String filename, duke@1: String relativePath) throws IOException { duke@1: super(configuration, path, filename); duke@1: this.configuration = configuration; duke@1: this.path = path; duke@1: this.relativePath = relativePath; duke@1: this.relativepathNoSlash = duke@1: DirectoryManager.getPathNoTrailingSlash(this.relativePath); duke@1: this.filename = filename; duke@1: } duke@1: duke@1: /** duke@1: * Replace {@docRoot} tag used in options that accept HTML text, such duke@1: * as -header, -footer, -top and -bottom, and when converting a relative duke@1: * HREF where commentTagsToString inserts a {@docRoot} where one was duke@1: * missing. (Also see DocRootTaglet for {@docRoot} tags in doc duke@1: * comments.) duke@1: *

duke@1: * Replace {@docRoot} tag in htmlstr with the relative path to the duke@1: * destination directory from the directory where the file is being duke@1: * written, looping to handle all such tags in htmlstr. duke@1: *

duke@1: * For example, for "-d docs" and -header containing {@docRoot}, when duke@1: * the HTML page for source file p/C1.java is being generated, the duke@1: * {@docRoot} tag would be inserted into the header as "../", duke@1: * the relative path from docs/p/ to docs/ (the document root). duke@1: *

duke@1: * Note: This doc comment was written with '&#064;' representing '@' duke@1: * to prevent the inline tag from being interpreted. duke@1: */ duke@1: public String replaceDocRootDir(String htmlstr) { duke@1: // Return if no inline tags exist duke@1: int index = htmlstr.indexOf("{@"); duke@1: if (index < 0) { duke@1: return htmlstr; duke@1: } duke@1: String lowerHtml = htmlstr.toLowerCase(); duke@1: // Return index of first occurrence of {@docroot} duke@1: // Note: {@docRoot} is not case sensitive when passed in w/command line option duke@1: index = lowerHtml.indexOf("{@docroot}", index); duke@1: if (index < 0) { duke@1: return htmlstr; duke@1: } jjg@910: StringBuilder buf = new StringBuilder(); duke@1: int previndex = 0; duke@1: while (true) { bpatel@997: if (configuration.docrootparent.length() > 0) { bpatel@997: // Search for lowercase version of {@docRoot}/.. bpatel@997: index = lowerHtml.indexOf("{@docroot}/..", previndex); bpatel@997: // If next {@docRoot}/.. pattern not found, append rest of htmlstr and exit loop bpatel@997: if (index < 0) { bpatel@997: buf.append(htmlstr.substring(previndex)); bpatel@997: break; bpatel@997: } bpatel@997: // If next {@docroot}/.. pattern found, append htmlstr up to start of tag bpatel@997: buf.append(htmlstr.substring(previndex, index)); bpatel@997: previndex = index + 13; // length for {@docroot}/.. string bpatel@997: // Insert docrootparent absolute path where {@docRoot}/.. was located bpatel@997: bpatel@997: buf.append(configuration.docrootparent); bpatel@997: // Append slash if next character is not a slash bpatel@997: if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') { bpatel@997: buf.append(DirectoryManager.URL_FILE_SEPARATOR); bpatel@997: } bpatel@997: } else { bpatel@997: // Search for lowercase version of {@docRoot} bpatel@997: index = lowerHtml.indexOf("{@docroot}", previndex); bpatel@997: // If next {@docRoot} tag not found, append rest of htmlstr and exit loop bpatel@997: if (index < 0) { bpatel@997: buf.append(htmlstr.substring(previndex)); bpatel@997: break; bpatel@997: } bpatel@997: // If next {@docroot} tag found, append htmlstr up to start of tag bpatel@997: buf.append(htmlstr.substring(previndex, index)); bpatel@997: previndex = index + 10; // length for {@docroot} string bpatel@997: // Insert relative path where {@docRoot} was located bpatel@997: buf.append(relativepathNoSlash); bpatel@997: // Append slash if next character is not a slash bpatel@997: if (relativepathNoSlash.length() > 0 && previndex < htmlstr.length() && bpatel@997: htmlstr.charAt(previndex) != '/') { bpatel@997: buf.append(DirectoryManager.URL_FILE_SEPARATOR); bpatel@997: } duke@1: } duke@1: } duke@1: return buf.toString(); duke@1: } duke@1: duke@1: /** duke@1: * Print Html Hyper Link, with target frame. This duke@1: * link will only appear if page is not in a frame. duke@1: * duke@1: * @param link String name of the file. duke@1: * @param where Position in the file duke@1: * @param target Name of the target frame. duke@1: * @param label Tag for the link. bpatel@182: * @param strong Whether the label should be strong or not? duke@1: */ duke@1: public void printNoFramesTargetHyperLink(String link, String where, duke@1: String target, String label, bpatel@182: boolean strong) { duke@1: script(); duke@1: println(" "); duke@1: scriptEnd(); duke@1: noScript(); bpatel@766: println(" " + getHyperLinkString(link, where, label, strong, "", "", target)); duke@1: noScriptEnd(); duke@1: println(DocletConstants.NL); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Get the script to show or hide the All classes link. bpatel@766: * bpatel@766: * @param id id of the element to show or hide bpatel@766: * @return a content tree for the script bpatel@766: */ bpatel@766: public Content getAllClassesLinkScript(String id) { bpatel@766: HtmlTree script = new HtmlTree(HtmlTag.SCRIPT); bpatel@766: script.addAttr(HtmlAttr.TYPE, "text/javascript"); bpatel@793: String scriptCode = "" + DocletConstants.NL; bpatel@766: Content scriptContent = new RawHtml(scriptCode); bpatel@766: script.addContent(scriptContent); bpatel@766: Content div = HtmlTree.DIV(script); bpatel@766: return div; bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Add method information. bpatel@766: * bpatel@766: * @param method the method to be documented bpatel@766: * @param dl the content tree to which the method information will be added bpatel@766: */ bpatel@766: private void addMethodInfo(MethodDoc method, Content dl) { duke@1: ClassDoc[] intfacs = method.containingClass().interfaces(); duke@1: MethodDoc overriddenMethod = method.overriddenMethod(); bpatel@233: // Check whether there is any implementation or overridden info to be bpatel@233: // printed. If no overridden or implementation info needs to be bpatel@233: // printed, do not print this section. bpatel@233: if ((intfacs.length > 0 && bpatel@233: new ImplementedMethods(method, this.configuration).build().length > 0) || bpatel@233: overriddenMethod != null) { bpatel@766: MethodWriterImpl.addImplementsInfo(this, method, dl); duke@1: if (overriddenMethod != null) { bpatel@766: MethodWriterImpl.addOverridden(this, bpatel@766: method.overriddenType(), overriddenMethod, dl); duke@1: } duke@1: } duke@1: } duke@1: bpatel@766: /** bpatel@766: * Adds the tags information. bpatel@766: * bpatel@766: * @param doc the doc for which the tags will be generated bpatel@766: * @param htmltree the documentation tree to which the tags will be added bpatel@766: */ bpatel@766: protected void addTagsInfo(Doc doc, Content htmltree) { bpatel@766: if (configuration.nocomment) { duke@1: return; duke@1: } bpatel@766: Content dl = new HtmlTree(HtmlTag.DL); duke@1: if (doc instanceof MethodDoc) { bpatel@766: addMethodInfo((MethodDoc) doc, dl); duke@1: } duke@1: TagletOutputImpl output = new TagletOutputImpl(""); duke@1: TagletWriter.genTagOuput(configuration.tagletManager, doc, duke@1: configuration.tagletManager.getCustomTags(doc), duke@1: getTagletWriterInstance(false), output); bpatel@233: String outputString = output.toString().trim(); bpatel@233: if (!outputString.isEmpty()) { bpatel@766: Content resultString = new RawHtml(outputString); bpatel@766: dl.addContent(resultString); duke@1: } bpatel@766: htmltree.addContent(dl); duke@1: } duke@1: duke@1: /** bpatel@233: * Check whether there are any tags for Serialization Overview bpatel@233: * section to be printed. bpatel@222: * bpatel@233: * @param field the FieldDoc object to check for tags. bpatel@222: * @return true if there are tags to be printed else return false. bpatel@222: */ bpatel@233: protected boolean hasSerializationOverviewTags(FieldDoc field) { bpatel@222: TagletOutputImpl output = new TagletOutputImpl(""); bpatel@233: TagletWriter.genTagOuput(configuration.tagletManager, field, bpatel@233: configuration.tagletManager.getCustomTags(field), bpatel@222: getTagletWriterInstance(false), output); bpatel@233: return (!output.toString().trim().isEmpty()); bpatel@222: } bpatel@222: bpatel@222: /** duke@1: * Returns a TagletWriter that knows how to write HTML. duke@1: * duke@1: * @return a TagletWriter that knows how to write HTML. duke@1: */ duke@1: public TagletWriter getTagletWriterInstance(boolean isFirstSentence) { duke@1: return new TagletWriterImpl(this, isFirstSentence); duke@1: } duke@1: duke@1: protected void printTagsInfoHeader() { duke@1: dl(); duke@1: } duke@1: duke@1: protected void printTagsInfoFooter() { duke@1: dlEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get Package link, with target frame. duke@1: * bpatel@766: * @param pd The link will be to the "package-summary.html" page for this package bpatel@766: * @param target name of the target frame bpatel@766: * @param label tag for the link bpatel@766: * @return a content for the target package link duke@1: */ bpatel@766: public Content getTargetPackageLink(PackageDoc pd, String target, bpatel@766: Content label) { bpatel@766: return getHyperLink(pathString(pd, "package-summary.html"), "", label, "", target); duke@1: } duke@1: duke@1: /** duke@1: * Print the html file header. Also print Html page title and stylesheet duke@1: * default properties. duke@1: * duke@1: * @param title String window title to go in the <TITLE> tag duke@1: * @param metakeywords Array of String keywords for META tag. Each element duke@1: * of the array is assigned to a separate META tag. duke@1: * Pass in null for no array. duke@1: * @param includeScript boolean true if printing windowtitle script. duke@1: * False for files that appear in the left-hand frames. duke@1: */ duke@1: public void printHtmlHeader(String title, String[] metakeywords, duke@1: boolean includeScript) { duke@1: println(""); duke@1: println(""); duke@1: html(); duke@1: head(); duke@1: if (! configuration.notimestamp) { duke@1: print(""); duke@1: } duke@1: if (configuration.charset.length() > 0) { duke@1: println(""); duke@1: } duke@1: if ( configuration.windowtitle.length() > 0 ) { duke@1: title += " (" + configuration.windowtitle + ")"; duke@1: } duke@1: title(title); duke@1: println(title); duke@1: titleEnd(); duke@1: println(""); duke@1: if (! configuration.notimestamp) { duke@1: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); duke@1: println(""); duke@1: } duke@1: if ( metakeywords != null ) { duke@1: for ( int i=0; i < metakeywords.length; i++ ) { duke@1: println(""); duke@1: } duke@1: } duke@1: println(""); duke@1: printStyleSheetProperties(); duke@1: println(""); duke@1: // Don't print windowtitle script for overview-frame, allclasses-frame duke@1: // and package-frame duke@1: if (includeScript) { duke@1: printWinTitleScript(title); duke@1: } duke@1: println(""); duke@1: headEnd(); duke@1: println(""); duke@1: body("white", includeScript); duke@1: } duke@1: duke@1: /** bpatel@766: * Generates the HTML document tree and prints it out. bpatel@766: * bpatel@766: * @param metakeywords Array of String keywords for META tag. Each element bpatel@766: * of the array is assigned to a separate META tag. bpatel@766: * Pass in null for no array bpatel@766: * @param includeScript true if printing windowtitle script bpatel@766: * false for files that appear in the left-hand frames bpatel@766: * @param body the body htmltree to be included in the document bpatel@766: */ bpatel@766: public void printHtmlDocument(String[] metakeywords, boolean includeScript, bpatel@766: Content body) { bpatel@766: Content htmlDocType = DocType.Transitional(); bpatel@766: Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); bpatel@766: Content head = new HtmlTree(HtmlTag.HEAD); bpatel@766: if (!configuration.notimestamp) { bpatel@766: Content headComment = new Comment("Generated by javadoc (version " + bpatel@766: ConfigurationImpl.BUILD_DATE + ") on " + today()); bpatel@766: head.addContent(headComment); bpatel@766: } bpatel@766: if (configuration.charset.length() > 0) { bpatel@766: Content meta = HtmlTree.META("Content-Type", "text/html", bpatel@766: configuration.charset); bpatel@766: head.addContent(meta); bpatel@766: } bpatel@766: head.addContent(getTitle()); bpatel@766: if (!configuration.notimestamp) { bpatel@766: SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); bpatel@766: Content meta = HtmlTree.META("date", dateFormat.format(new Date())); bpatel@766: head.addContent(meta); bpatel@766: } bpatel@766: if (metakeywords != null) { bpatel@766: for (int i=0; i < metakeywords.length; i++) { bpatel@766: Content meta = HtmlTree.META("keywords", metakeywords[i]); bpatel@766: head.addContent(meta); bpatel@766: } bpatel@766: } bpatel@766: head.addContent(getStyleSheetProperties()); bpatel@766: Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), bpatel@766: head, body); bpatel@766: Content htmlDocument = new HtmlDocument(htmlDocType, bpatel@766: htmlComment, htmlTree); bpatel@766: print(htmlDocument.toString()); bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Get the window title. bpatel@766: * bpatel@766: * @param title the title string to construct the complete window title bpatel@766: * @return the window title string bpatel@766: */ bpatel@766: public String getWindowTitle(String title) { bpatel@766: if (configuration.windowtitle.length() > 0) { bpatel@766: title += " (" + configuration.windowtitle + ")"; bpatel@766: } bpatel@766: return title; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print user specified header and the footer. duke@1: * duke@1: * @param header if true print the user provided header else print the duke@1: * user provided footer. duke@1: */ duke@1: public void printUserHeaderFooter(boolean header) { duke@1: em(); duke@1: if (header) { duke@1: print(replaceDocRootDir(configuration.header)); duke@1: } else { duke@1: if (configuration.footer.length() != 0) { duke@1: print(replaceDocRootDir(configuration.footer)); duke@1: } else { duke@1: print(replaceDocRootDir(configuration.header)); duke@1: } duke@1: } duke@1: emEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get user specified header and the footer. bpatel@766: * bpatel@766: * @param header if true print the user provided header else print the bpatel@766: * user provided footer. bpatel@766: */ bpatel@766: public Content getUserHeaderFooter(boolean header) { bpatel@766: String content; bpatel@766: if (header) { bpatel@766: content = replaceDocRootDir(configuration.header); bpatel@766: } else { bpatel@766: if (configuration.footer.length() != 0) { bpatel@766: content = replaceDocRootDir(configuration.footer); bpatel@766: } else { bpatel@766: content = replaceDocRootDir(configuration.header); bpatel@766: } bpatel@766: } bpatel@766: Content rawContent = new RawHtml(content); bpatel@766: Content em = HtmlTree.EM(rawContent); bpatel@766: return em; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the user specified top. duke@1: */ duke@1: public void printTop() { duke@1: print(replaceDocRootDir(configuration.top)); duke@1: hr(); duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the user specified top. bpatel@766: * bpatel@766: * @param body the content tree to which user specified top will be added bpatel@766: */ bpatel@766: public void addTop(Content body) { bpatel@766: Content top = new RawHtml(replaceDocRootDir(configuration.top)); bpatel@766: body.addContent(top); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the user specified bottom. duke@1: */ duke@1: public void printBottom() { duke@1: hr(); duke@1: print(replaceDocRootDir(configuration.bottom)); duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the user specified bottom. bpatel@766: * bpatel@766: * @param body the content tree to which user specified bottom will be added bpatel@766: */ bpatel@766: public void addBottom(Content body) { bpatel@766: Content bottom = new RawHtml(replaceDocRootDir(configuration.bottom)); bpatel@766: Content small = HtmlTree.SMALL(bottom); bpatel@766: Content p = HtmlTree.P(HtmlStyle.legalCopy, small); bpatel@766: body.addContent(p); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the navigation bar for the Html page at the top and and the bottom. duke@1: * duke@1: * @param header If true print navigation bar at the top of the page else duke@1: * print the nevigation bar at the bottom. duke@1: */ duke@1: protected void navLinks(boolean header) { duke@1: println(""); duke@1: if (!configuration.nonavbar) { duke@1: if (header) { duke@1: println(DocletConstants.NL + ""); duke@1: anchor("navbar_top"); duke@1: println(); bpatel@766: print(getHyperLinkString("", "skip-navbar_top", "", false, "", duke@1: configuration.getText("doclet.Skip_navigation_links"), "")); duke@1: } else { duke@1: println(DocletConstants.NL + ""); duke@1: anchor("navbar_bottom"); duke@1: println(); bpatel@766: print(getHyperLinkString("", "skip-navbar_bottom", "", false, "", duke@1: configuration.getText("doclet.Skip_navigation_links"), "")); duke@1: } duke@1: table(0, "100%", 1, 0); duke@1: tr(); duke@1: tdColspanBgcolorStyle(2, "#EEEEFF", "NavBarCell1"); duke@1: println(""); duke@1: if (header) { duke@1: anchor("navbar_top_firstrow"); duke@1: } else { duke@1: anchor("navbar_bottom_firstrow"); duke@1: } duke@1: table(0, 0, 3); duke@1: print(" "); duke@1: trAlignVAlign("center", "top"); duke@1: duke@1: if (configuration.createoverview) { duke@1: navLinkContents(); duke@1: } duke@1: duke@1: if (configuration.packages.length == 1) { duke@1: navLinkPackage(configuration.packages[0]); duke@1: } else if (configuration.packages.length > 1) { duke@1: navLinkPackage(); duke@1: } duke@1: duke@1: navLinkClass(); duke@1: duke@1: if(configuration.classuse) { duke@1: navLinkClassUse(); duke@1: } duke@1: if(configuration.createtree) { duke@1: navLinkTree(); duke@1: } duke@1: if(!(configuration.nodeprecated || duke@1: configuration.nodeprecatedlist)) { duke@1: navLinkDeprecated(); duke@1: } duke@1: if(configuration.createindex) { duke@1: navLinkIndex(); duke@1: } duke@1: if (!configuration.nohelp) { duke@1: navLinkHelp(); duke@1: } duke@1: print(" "); duke@1: trEnd(); duke@1: tableEnd(); duke@1: tdEnd(); duke@1: duke@1: tdAlignVAlignRowspan("right", "top", 3); duke@1: duke@1: printUserHeaderFooter(header); duke@1: tdEnd(); duke@1: trEnd(); duke@1: println(""); duke@1: duke@1: tr(); duke@1: tdBgcolorStyle("white", "NavBarCell2"); duke@1: font("-2"); duke@1: space(); duke@1: navLinkPrevious(); duke@1: space(); duke@1: println(""); duke@1: space(); duke@1: navLinkNext(); duke@1: fontEnd(); duke@1: tdEnd(); duke@1: duke@1: tdBgcolorStyle("white", "NavBarCell2"); duke@1: font("-2"); duke@1: print(" "); duke@1: navShowLists(); duke@1: print(" "); duke@1: space(); duke@1: println(""); duke@1: space(); duke@1: navHideLists(filename); duke@1: print(" "); duke@1: space(); duke@1: println(""); duke@1: space(); duke@1: navLinkClassIndex(); duke@1: fontEnd(); duke@1: tdEnd(); duke@1: duke@1: trEnd(); duke@1: duke@1: printSummaryDetailLinks(); duke@1: duke@1: tableEnd(); duke@1: if (header) { duke@1: aName("skip-navbar_top"); duke@1: aEnd(); duke@1: println(DocletConstants.NL + ""); duke@1: } else { duke@1: aName("skip-navbar_bottom"); duke@1: aEnd(); duke@1: println(DocletConstants.NL + ""); duke@1: } duke@1: println(""); duke@1: } duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the navigation bar for the Html page at the top and and the bottom. bpatel@766: * bpatel@766: * @param header If true print navigation bar at the top of the page else bpatel@766: * @param body the HtmlTree to which the nav links will be added bpatel@766: */ bpatel@766: protected void addNavLinks(boolean header, Content body) { bpatel@766: if (!configuration.nonavbar) { bpatel@766: String allClassesId = "allclasses_"; bpatel@766: HtmlTree navDiv = new HtmlTree(HtmlTag.DIV); bpatel@766: if (header) { bpatel@766: body.addContent(HtmlConstants.START_OF_TOP_NAVBAR); bpatel@766: navDiv.addStyle(HtmlStyle.topNav); bpatel@766: allClassesId += "navbar_top"; bpatel@766: Content a = getMarkerAnchor("navbar_top"); bpatel@766: navDiv.addContent(a); bpatel@766: Content skipLinkContent = getHyperLink("", bpatel@766: "skip-navbar_top", HtmlTree.EMPTY, configuration.getText( bpatel@766: "doclet.Skip_navigation_links"), ""); bpatel@766: navDiv.addContent(skipLinkContent); bpatel@766: } else { bpatel@766: body.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR); bpatel@766: navDiv.addStyle(HtmlStyle.bottomNav); bpatel@766: allClassesId += "navbar_bottom"; bpatel@766: Content a = getMarkerAnchor("navbar_bottom"); bpatel@766: navDiv.addContent(a); bpatel@766: Content skipLinkContent = getHyperLink("", bpatel@766: "skip-navbar_bottom", HtmlTree.EMPTY, configuration.getText( bpatel@766: "doclet.Skip_navigation_links"), ""); bpatel@766: navDiv.addContent(skipLinkContent); bpatel@766: } bpatel@766: if (header) { bpatel@766: navDiv.addContent(getMarkerAnchor("navbar_top_firstrow")); bpatel@766: } else { bpatel@766: navDiv.addContent(getMarkerAnchor("navbar_bottom_firstrow")); bpatel@766: } bpatel@766: HtmlTree navList = new HtmlTree(HtmlTag.UL); bpatel@766: navList.addStyle(HtmlStyle.navList); bpatel@766: navList.addAttr(HtmlAttr.TITLE, "Navigation"); bpatel@766: if (configuration.createoverview) { bpatel@766: navList.addContent(getNavLinkContents()); bpatel@766: } bpatel@766: if (configuration.packages.length == 1) { bpatel@766: navList.addContent(getNavLinkPackage(configuration.packages[0])); bpatel@766: } else if (configuration.packages.length > 1) { bpatel@766: navList.addContent(getNavLinkPackage()); bpatel@766: } bpatel@766: navList.addContent(getNavLinkClass()); bpatel@766: if(configuration.classuse) { bpatel@766: navList.addContent(getNavLinkClassUse()); bpatel@766: } bpatel@766: if(configuration.createtree) { bpatel@766: navList.addContent(getNavLinkTree()); bpatel@766: } bpatel@766: if(!(configuration.nodeprecated || bpatel@766: configuration.nodeprecatedlist)) { bpatel@766: navList.addContent(getNavLinkDeprecated()); bpatel@766: } bpatel@766: if(configuration.createindex) { bpatel@766: navList.addContent(getNavLinkIndex()); bpatel@766: } bpatel@766: if (!configuration.nohelp) { bpatel@766: navList.addContent(getNavLinkHelp()); bpatel@766: } bpatel@766: navDiv.addContent(navList); bpatel@766: Content aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, getUserHeaderFooter(header)); bpatel@766: navDiv.addContent(aboutDiv); bpatel@766: body.addContent(navDiv); bpatel@766: Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious()); bpatel@766: ulNav.addContent(getNavLinkNext()); bpatel@766: Content subDiv = HtmlTree.DIV(HtmlStyle.subNav, ulNav); bpatel@766: Content ulFrames = HtmlTree.UL(HtmlStyle.navList, getNavShowLists()); bpatel@766: ulFrames.addContent(getNavHideLists(filename)); bpatel@766: subDiv.addContent(ulFrames); bpatel@766: HtmlTree ulAllClasses = HtmlTree.UL(HtmlStyle.navList, getNavLinkClassIndex()); bpatel@766: ulAllClasses.addAttr(HtmlAttr.ID, allClassesId.toString()); bpatel@766: subDiv.addContent(ulAllClasses); bpatel@766: subDiv.addContent(getAllClassesLinkScript(allClassesId.toString())); bpatel@766: addSummaryDetailLinks(subDiv); bpatel@766: if (header) { bpatel@766: subDiv.addContent(getMarkerAnchor("skip-navbar_top")); bpatel@766: body.addContent(subDiv); bpatel@766: body.addContent(HtmlConstants.END_OF_TOP_NAVBAR); bpatel@766: } else { bpatel@766: subDiv.addContent(getMarkerAnchor("skip-navbar_bottom")); bpatel@766: body.addContent(subDiv); bpatel@766: body.addContent(HtmlConstants.END_OF_BOTTOM_NAVBAR); bpatel@766: } bpatel@766: } bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the word "NEXT" to indicate that no link is available. Override duke@1: * this method to customize next link. duke@1: */ duke@1: protected void navLinkNext() { duke@1: navLinkNext(null); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the word "NEXT" to indicate that no link is available. Override bpatel@766: * this method to customize next link. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkNext() { bpatel@766: return getNavLinkNext(null); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the word "PREV" to indicate that no link is available. Override duke@1: * this method to customize prev link. duke@1: */ duke@1: protected void navLinkPrevious() { duke@1: navLinkPrevious(null); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the word "PREV" to indicate that no link is available. Override bpatel@766: * this method to customize prev link. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkPrevious() { bpatel@766: return getNavLinkPrevious(null); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Do nothing. This is the default method. duke@1: */ duke@1: protected void printSummaryDetailLinks() { duke@1: } duke@1: duke@1: /** bpatel@766: * Do nothing. This is the default method. bpatel@766: */ bpatel@766: protected void addSummaryDetailLinks(Content navDiv) { bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print link to the "overview-summary.html" page. duke@1: */ duke@1: protected void navLinkContents() { duke@1: navCellStart(); duke@1: printHyperLink(relativePath + "overview-summary.html", "", duke@1: configuration.getText("doclet.Overview"), true, "NavBarFont1"); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get link to the "overview-summary.html" page. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkContents() { bpatel@766: Content linkContent = getHyperLink(relativePath + bpatel@766: "overview-summary.html", "", overviewLabel, "", ""); bpatel@766: Content li = HtmlTree.LI(linkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Description for a cell in the navigation bar. duke@1: */ duke@1: protected void navCellStart() { duke@1: print(" "); duke@1: tdBgcolorStyle("#EEEEFF", "NavBarCell1"); duke@1: print(" "); duke@1: } duke@1: duke@1: /** duke@1: * Description for a cell in the navigation bar, but with reverse duke@1: * high-light effect. duke@1: */ duke@1: protected void navCellRevStart() { duke@1: print(" "); duke@1: tdBgcolorStyle("#FFFFFF", "NavBarCell1Rev"); duke@1: print(" "); duke@1: space(); duke@1: } duke@1: duke@1: /** duke@1: * Closing tag for navigation bar cell. duke@1: */ duke@1: protected void navCellEnd() { duke@1: space(); duke@1: tdEnd(); duke@1: } duke@1: duke@1: /** duke@1: * Print link to the "package-summary.html" page for the package passed. duke@1: * duke@1: * @param pkg Package to which link will be generated. duke@1: */ duke@1: protected void navLinkPackage(PackageDoc pkg) { duke@1: navCellStart(); duke@1: printPackageLink(pkg, configuration.getText("doclet.Package"), true, duke@1: "NavBarFont1"); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get link to the "package-summary.html" page for the package passed. bpatel@766: * bpatel@766: * @param pkg Package to which link will be generated bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkPackage(PackageDoc pkg) { bpatel@766: Content linkContent = getPackageLink(pkg, bpatel@766: packageLabel); bpatel@766: Content li = HtmlTree.LI(linkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the word "Package" in the navigation bar cell, to indicate that duke@1: * link is not available here. duke@1: */ duke@1: protected void navLinkPackage() { duke@1: navCellStart(); duke@1: fontStyle("NavBarFont1"); duke@1: printText("doclet.Package"); duke@1: fontEnd(); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the word "Package" , to indicate that link is not available here. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkPackage() { bpatel@766: Content li = HtmlTree.LI(packageLabel); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the word "Use" in the navigation bar cell, to indicate that link duke@1: * is not available. duke@1: */ duke@1: protected void navLinkClassUse() { duke@1: navCellStart(); duke@1: fontStyle("NavBarFont1"); duke@1: printText("doclet.navClassUse"); duke@1: fontEnd(); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the word "Use", to indicate that link is not available. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkClassUse() { bpatel@766: Content li = HtmlTree.LI(useLabel); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print link for previous file. duke@1: * duke@1: * @param prev File name for the prev link. duke@1: */ duke@1: public void navLinkPrevious(String prev) { duke@1: String tag = configuration.getText("doclet.Prev"); duke@1: if (prev != null) { duke@1: printHyperLink(prev, "", tag, true) ; duke@1: } else { duke@1: print(tag); duke@1: } duke@1: } duke@1: duke@1: /** bpatel@766: * Get link for previous file. bpatel@766: * bpatel@766: * @param prev File name for the prev link bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: public Content getNavLinkPrevious(String prev) { bpatel@766: Content li; bpatel@766: if (prev != null) { bpatel@766: li = HtmlTree.LI(getHyperLink(prev, "", prevLabel, "", "")); bpatel@766: } bpatel@766: else bpatel@766: li = HtmlTree.LI(prevLabel); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print link for next file. If next is null, just print the label duke@1: * without linking it anywhere. duke@1: * duke@1: * @param next File name for the next link. duke@1: */ duke@1: public void navLinkNext(String next) { duke@1: String tag = configuration.getText("doclet.Next"); duke@1: if (next != null) { duke@1: printHyperLink(next, "", tag, true); duke@1: } else { duke@1: print(tag); duke@1: } duke@1: } duke@1: duke@1: /** bpatel@766: * Get link for next file. If next is null, just print the label bpatel@766: * without linking it anywhere. bpatel@766: * bpatel@766: * @param next File name for the next link bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: public Content getNavLinkNext(String next) { bpatel@766: Content li; bpatel@766: if (next != null) { bpatel@766: li = HtmlTree.LI(getHyperLink(next, "", nextLabel, "", "")); bpatel@766: } bpatel@766: else bpatel@766: li = HtmlTree.LI(nextLabel); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print "FRAMES" link, to switch to the frame version of the output. duke@1: * duke@1: * @param link File to be linked, "index.html". duke@1: */ duke@1: protected void navShowLists(String link) { bpatel@766: print(getHyperLinkString(link + "?" + path + filename, "", duke@1: configuration.getText("doclet.FRAMES"), true, "", "", "_top")); duke@1: } duke@1: duke@1: /** bpatel@766: * Get "FRAMES" link, to switch to the frame version of the output. bpatel@766: * bpatel@766: * @param link File to be linked, "index.html" bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavShowLists(String link) { bpatel@766: Content framesContent = getHyperLink(link + "?" + path + bpatel@766: filename, "", framesLabel, "", "_top"); bpatel@766: Content li = HtmlTree.LI(framesContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print "FRAMES" link, to switch to the frame version of the output. duke@1: */ duke@1: protected void navShowLists() { duke@1: navShowLists(relativePath + "index.html"); duke@1: } duke@1: duke@1: /** bpatel@766: * Get "FRAMES" link, to switch to the frame version of the output. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavShowLists() { bpatel@766: return getNavShowLists(relativePath + "index.html"); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print "NO FRAMES" link, to switch to the non-frame version of the output. duke@1: * duke@1: * @param link File to be linked. duke@1: */ duke@1: protected void navHideLists(String link) { bpatel@766: print(getHyperLinkString(link, "", configuration.getText("doclet.NO_FRAMES"), duke@1: true, "", "", "_top")); duke@1: } duke@1: duke@1: /** bpatel@766: * Get "NO FRAMES" link, to switch to the non-frame version of the output. bpatel@766: * bpatel@766: * @param link File to be linked bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavHideLists(String link) { bpatel@766: Content noFramesContent = getHyperLink(link, "", noframesLabel, "", "_top"); bpatel@766: Content li = HtmlTree.LI(noFramesContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print "Tree" link in the navigation bar. If there is only one package duke@1: * specified on the command line, then the "Tree" link will be to the duke@1: * only "package-tree.html" file otherwise it will be to the duke@1: * "overview-tree.html" file. duke@1: */ duke@1: protected void navLinkTree() { duke@1: navCellStart(); duke@1: PackageDoc[] packages = configuration.root.specifiedPackages(); duke@1: if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) { duke@1: printHyperLink(pathString(packages[0], "package-tree.html"), "", duke@1: configuration.getText("doclet.Tree"), true, "NavBarFont1"); duke@1: } else { duke@1: printHyperLink(relativePath + "overview-tree.html", "", duke@1: configuration.getText("doclet.Tree"), true, "NavBarFont1"); duke@1: } duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get "Tree" link in the navigation bar. If there is only one package bpatel@766: * specified on the command line, then the "Tree" link will be to the bpatel@766: * only "package-tree.html" file otherwise it will be to the bpatel@766: * "overview-tree.html" file. bpatel@766: * bpatel@766: * @return a content tree for the link duke@1: */ bpatel@766: protected Content getNavLinkTree() { bpatel@766: Content treeLinkContent; bpatel@766: PackageDoc[] packages = configuration.root.specifiedPackages(); bpatel@766: if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) { bpatel@766: treeLinkContent = getHyperLink(pathString(packages[0], bpatel@766: "package-tree.html"), "", treeLabel, bpatel@766: "", ""); bpatel@766: } else { bpatel@766: treeLinkContent = getHyperLink(relativePath + "overview-tree.html", bpatel@766: "", treeLabel, "", ""); bpatel@766: } bpatel@766: Content li = HtmlTree.LI(treeLinkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Get the overview tree link for the main tree. bpatel@766: * bpatel@766: * @param label the label for the link bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkMainTree(String label) { bpatel@766: Content mainTreeContent = getHyperLink(relativePath + "overview-tree.html", bpatel@766: new StringContent(label)); bpatel@766: Content li = HtmlTree.LI(mainTreeContent); bpatel@766: return li; duke@1: } duke@1: duke@1: /** duke@1: * Print the word "Class" in the navigation bar cell, to indicate that duke@1: * class link is not available. duke@1: */ duke@1: protected void navLinkClass() { duke@1: navCellStart(); duke@1: fontStyle("NavBarFont1"); duke@1: printText("doclet.Class"); duke@1: fontEnd(); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the word "Class", to indicate that class link is not available. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkClass() { bpatel@766: Content li = HtmlTree.LI(classLabel); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print "Deprecated" API link in the navigation bar. duke@1: */ duke@1: protected void navLinkDeprecated() { duke@1: navCellStart(); duke@1: printHyperLink(relativePath + "deprecated-list.html", "", duke@1: configuration.getText("doclet.navDeprecated"), true, "NavBarFont1"); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get "Deprecated" API link in the navigation bar. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkDeprecated() { bpatel@766: Content linkContent = getHyperLink(relativePath + bpatel@766: "deprecated-list.html", "", deprecatedLabel, "", ""); bpatel@766: Content li = HtmlTree.LI(linkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print link for generated index. If the user has used "-splitindex" duke@1: * command line option, then link to file "index-files/index-1.html" is duke@1: * generated otherwise link to file "index-all.html" is generated. duke@1: */ duke@1: protected void navLinkClassIndex() { duke@1: printNoFramesTargetHyperLink(relativePath + duke@1: AllClassesFrameWriter.OUTPUT_FILE_NAME_NOFRAMES, duke@1: "", "", configuration.getText("doclet.All_Classes"), true); duke@1: } bpatel@766: bpatel@766: /** bpatel@766: * Get link for generated index. If the user has used "-splitindex" bpatel@766: * command line option, then link to file "index-files/index-1.html" is bpatel@766: * generated otherwise link to file "index-all.html" is generated. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkClassIndex() { bpatel@766: Content allClassesContent = getHyperLink(relativePath + bpatel@766: AllClassesFrameWriter.OUTPUT_FILE_NAME_NOFRAMES, "", bpatel@766: allclassesLabel, "", ""); bpatel@766: Content li = HtmlTree.LI(allClassesContent); bpatel@766: return li; bpatel@766: } duke@1: /** duke@1: * Print link for generated class index. duke@1: */ duke@1: protected void navLinkIndex() { duke@1: navCellStart(); duke@1: printHyperLink(relativePath + duke@1: (configuration.splitindex? duke@1: DirectoryManager.getPath("index-files") + duke@1: fileseparator: "") + duke@1: (configuration.splitindex? duke@1: "index-1.html" : "index-all.html"), "", duke@1: configuration.getText("doclet.Index"), true, "NavBarFont1"); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get link for generated class index. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkIndex() { bpatel@766: Content linkContent = getHyperLink(relativePath +(configuration.splitindex? bpatel@766: DirectoryManager.getPath("index-files") + fileseparator: "") + bpatel@766: (configuration.splitindex?"index-1.html" : "index-all.html"), "", bpatel@766: indexLabel, "", ""); bpatel@766: Content li = HtmlTree.LI(linkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print help file link. If user has provided a help file, then generate a duke@1: * link to the user given file, which is already copied to current or duke@1: * destination directory. duke@1: */ duke@1: protected void navLinkHelp() { duke@1: String helpfilenm = configuration.helpfile; duke@1: if (helpfilenm.equals("")) { duke@1: helpfilenm = "help-doc.html"; duke@1: } else { duke@1: int lastsep; duke@1: if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) { duke@1: helpfilenm = helpfilenm.substring(lastsep + 1); duke@1: } duke@1: } duke@1: navCellStart(); duke@1: printHyperLink(relativePath + helpfilenm, "", duke@1: configuration.getText("doclet.Help"), true, "NavBarFont1"); duke@1: navCellEnd(); duke@1: } duke@1: duke@1: /** bpatel@766: * Get help file link. If user has provided a help file, then generate a bpatel@766: * link to the user given file, which is already copied to current or bpatel@766: * destination directory. bpatel@766: * bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: protected Content getNavLinkHelp() { bpatel@766: String helpfilenm = configuration.helpfile; bpatel@766: if (helpfilenm.equals("")) { bpatel@766: helpfilenm = "help-doc.html"; bpatel@766: } else { bpatel@766: int lastsep; bpatel@766: if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) { bpatel@766: helpfilenm = helpfilenm.substring(lastsep + 1); bpatel@766: } bpatel@766: } bpatel@766: Content linkContent = getHyperLink(relativePath + helpfilenm, "", bpatel@766: helpLabel, "", ""); bpatel@766: Content li = HtmlTree.LI(linkContent); bpatel@766: return li; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Print the word "Detail" in the navigation bar. No link is available. duke@1: */ duke@1: protected void navDetail() { duke@1: printText("doclet.Detail"); duke@1: } duke@1: duke@1: /** duke@1: * Print the word "Summary" in the navigation bar. No link is available. duke@1: */ duke@1: protected void navSummary() { duke@1: printText("doclet.Summary"); duke@1: } duke@1: duke@1: /** duke@1: * Print the Html table tag for the index summary tables. The table tag duke@1: * printed is jjg@1326: * {@code } duke@1: */ duke@1: public void tableIndexSummary() { duke@1: table(1, "100%", 3, 0); duke@1: } duke@1: duke@1: /** bpatel@243: * Print the Html table tag for the index summary tables. bpatel@243: * bpatel@243: * @param summary the summary for the table tag summary attribute. bpatel@243: */ bpatel@243: public void tableIndexSummary(String summary) { bpatel@243: table(1, "100%", 3, 0, summary); bpatel@243: } bpatel@243: bpatel@243: /** duke@1: * Same as {@link #tableIndexSummary()}. duke@1: */ duke@1: public void tableIndexDetail() { duke@1: table(1, "100%", 3, 0); duke@1: } duke@1: duke@1: /** duke@1: * Print Html tag for table elements. The tag printed is duke@1: * <TD ALIGN="right" VALIGN="top" WIDTH="1%">. duke@1: */ duke@1: public void tdIndex() { duke@1: print("", "", "", duke@1: "", "

", "

", duke@1: "
  • ", "
  • ", "
    ", "
    ", duke@1: "", "", "
    ", "
    ", duke@1: "

    ", "

    ", "

    ", "

    ", duke@1: "

    ", "

    ", "

    ", "

    ", duke@1: "
    ", "
    ", "
    ", "
    ", duke@1: "
    ", "
    ", "", "", duke@1: "", "", "
    ", duke@1: "
    ", "
    ", duke@1: "
    ", "
    ", duke@1: "", "
      ", "
    ", duke@1: "
    ", "
    ", "
    "); duke@1: } duke@1: duke@1: /** bpatel@243: * Print table caption. bpatel@243: */ bpatel@243: public void tableCaptionStart() { bpatel@243: captionStyle("TableCaption"); bpatel@243: } bpatel@243: bpatel@243: /** bpatel@243: * Print table sub-caption. bpatel@243: */ bpatel@243: public void tableSubCaptionStart() { bpatel@243: captionStyle("TableSubCaption"); bpatel@243: } bpatel@243: bpatel@243: /** bpatel@243: * Print table caption end tags. bpatel@243: */ bpatel@243: public void tableCaptionEnd() { bpatel@243: captionEnd(); bpatel@243: } bpatel@243: bpatel@243: /** bpatel@243: * Print summary table header. bpatel@243: */ bpatel@243: public void summaryTableHeader(String[] header, String scope) { bpatel@243: tr(); bpatel@243: for ( int i=0; i < header.length; i++ ) { bpatel@243: thScopeNoWrap("TableHeader", scope); bpatel@243: print(header[i]); bpatel@243: thEnd(); bpatel@243: } bpatel@243: trEnd(); bpatel@243: } bpatel@243: bpatel@243: /** bpatel@766: * Get summary table header. bpatel@766: * bpatel@766: * @param header the header for the table bpatel@766: * @param scope the scope of the headers bpatel@766: * @return a content tree for the header bpatel@766: */ bpatel@766: public Content getSummaryTableHeader(String[] header, String scope) { bpatel@766: Content tr = new HtmlTree(HtmlTag.TR); bpatel@766: int size = header.length; bpatel@766: Content tableHeader; bpatel@766: if (size == 1) { bpatel@766: tableHeader = new StringContent(header[0]); bpatel@766: tr.addContent(HtmlTree.TH(HtmlStyle.colOne, scope, tableHeader)); bpatel@766: return tr; bpatel@766: } bpatel@766: for (int i = 0; i < size; i++) { bpatel@766: tableHeader = new StringContent(header[i]); bpatel@766: if(i == 0) bpatel@766: tr.addContent(HtmlTree.TH(HtmlStyle.colFirst, scope, tableHeader)); bpatel@766: else if(i == (size - 1)) bpatel@766: tr.addContent(HtmlTree.TH(HtmlStyle.colLast, scope, tableHeader)); bpatel@766: else bpatel@766: tr.addContent(HtmlTree.TH(scope, tableHeader)); bpatel@766: } bpatel@766: return tr; bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Get table caption. bpatel@766: * bpatel@766: * @param rawText the caption for the table which could be raw Html bpatel@766: * @return a content tree for the caption bpatel@766: */ bpatel@766: public Content getTableCaption(String rawText) { bpatel@766: Content title = new RawHtml(rawText); bpatel@766: Content captionSpan = HtmlTree.SPAN(title); bpatel@766: Content space = getSpace(); bpatel@766: Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, space); bpatel@766: Content caption = HtmlTree.CAPTION(captionSpan); bpatel@766: caption.addContent(tabSpan); bpatel@766: return caption; bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Get the marker anchor which will be added to the documentation tree. bpatel@766: * bpatel@766: * @param anchorName the anchor name attribute bpatel@766: * @return a content tree for the marker anchor bpatel@766: */ bpatel@766: public Content getMarkerAnchor(String anchorName) { bpatel@766: return getMarkerAnchor(anchorName, null); bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Get the marker anchor which will be added to the documentation tree. bpatel@766: * bpatel@766: * @param anchorName the anchor name attribute bpatel@766: * @param anchorContent the content that should be added to the anchor bpatel@766: * @return a content tree for the marker anchor bpatel@766: */ bpatel@766: public Content getMarkerAnchor(String anchorName, Content anchorContent) { bpatel@766: if (anchorContent == null) bpatel@766: anchorContent = new Comment(" "); bpatel@766: Content markerAnchor = HtmlTree.A_NAME(anchorName, anchorContent); bpatel@766: return markerAnchor; bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Returns a packagename content. bpatel@766: * bpatel@766: * @param packageDoc the package to check bpatel@766: * @return package name content bpatel@766: */ bpatel@766: public Content getPackageName(PackageDoc packageDoc) { bpatel@766: return packageDoc == null || packageDoc.name().length() == 0 ? bpatel@766: defaultPackageLabel : bpatel@766: getPackageLabel(packageDoc.name()); bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Returns a package name label. bpatel@766: * bpatel@766: * @param parsedName the package name bpatel@766: * @return the package name content bpatel@766: */ bpatel@766: public Content getPackageLabel(String packageName) { bpatel@766: return new StringContent(packageName); bpatel@766: } bpatel@766: bpatel@766: /** bpatel@995: * Add package deprecation information to the documentation tree bpatel@995: * bpatel@995: * @param deprPkgs list of deprecated packages bpatel@995: * @param headingKey the caption for the deprecated package table bpatel@995: * @param tableSummary the summary for the deprecated package table bpatel@995: * @param tableHeader table headers for the deprecated package table bpatel@995: * @param contentTree the content tree to which the deprecated package table will be added bpatel@995: */ bpatel@995: protected void addPackageDeprecatedAPI(List deprPkgs, String headingKey, bpatel@995: String tableSummary, String[] tableHeader, Content contentTree) { bpatel@995: if (deprPkgs.size() > 0) { bpatel@995: Content table = HtmlTree.TABLE(0, 3, 0, tableSummary, bpatel@995: getTableCaption(configuration().getText(headingKey))); bpatel@995: table.addContent(getSummaryTableHeader(tableHeader, "col")); bpatel@995: Content tbody = new HtmlTree(HtmlTag.TBODY); bpatel@995: for (int i = 0; i < deprPkgs.size(); i++) { bpatel@995: PackageDoc pkg = (PackageDoc) deprPkgs.get(i); bpatel@995: HtmlTree td = HtmlTree.TD(HtmlStyle.colOne, bpatel@995: getPackageLink(pkg, getPackageName(pkg))); bpatel@995: if (pkg.tags("deprecated").length > 0) { bpatel@995: addInlineDeprecatedComment(pkg, pkg.tags("deprecated")[0], td); bpatel@995: } bpatel@995: HtmlTree tr = HtmlTree.TR(td); bpatel@995: if (i % 2 == 0) { bpatel@995: tr.addStyle(HtmlStyle.altColor); bpatel@995: } else { bpatel@995: tr.addStyle(HtmlStyle.rowColor); bpatel@995: } bpatel@995: tbody.addContent(tr); bpatel@995: } bpatel@995: table.addContent(tbody); bpatel@995: Content li = HtmlTree.LI(HtmlStyle.blockList, table); bpatel@995: Content ul = HtmlTree.UL(HtmlStyle.blockList, li); bpatel@995: contentTree.addContent(ul); bpatel@995: } bpatel@995: } bpatel@995: bpatel@995: /** duke@1: * Prine table header information about color, column span and the font. duke@1: * duke@1: * @param color Background color. duke@1: * @param span Column span. duke@1: */ duke@1: public void tableHeaderStart(String color, int span) { duke@1: trBgcolorStyle(color, "TableHeadingColor"); duke@1: thAlignColspan("left", span); duke@1: font("+2"); duke@1: } duke@1: duke@1: /** duke@1: * Print table header for the inherited members summary tables. Print the duke@1: * background color information. duke@1: * duke@1: * @param color Background color. duke@1: */ duke@1: public void tableInheritedHeaderStart(String color) { duke@1: trBgcolorStyle(color, "TableSubHeadingColor"); duke@1: thAlign("left"); duke@1: } duke@1: duke@1: /** duke@1: * Print "Use" table header. Print the background color and the column span. duke@1: * duke@1: * @param color Background color. duke@1: */ duke@1: public void tableUseInfoHeaderStart(String color) { duke@1: trBgcolorStyle(color, "TableSubHeadingColor"); duke@1: thAlignColspan("left", 2); duke@1: } duke@1: duke@1: /** duke@1: * Print table header with the background color with default column span 2. duke@1: * duke@1: * @param color Background color. duke@1: */ duke@1: public void tableHeaderStart(String color) { duke@1: tableHeaderStart(color, 2); duke@1: } duke@1: duke@1: /** duke@1: * Print table header with the column span, with the default color #CCCCFF. duke@1: * duke@1: * @param span Column span. duke@1: */ duke@1: public void tableHeaderStart(int span) { duke@1: tableHeaderStart("#CCCCFF", span); duke@1: } duke@1: duke@1: /** duke@1: * Print table header with default column span 2 and default color #CCCCFF. duke@1: */ duke@1: public void tableHeaderStart() { duke@1: tableHeaderStart(2); duke@1: } duke@1: duke@1: /** duke@1: * Print table header end tags for font, column and row. duke@1: */ duke@1: public void tableHeaderEnd() { duke@1: fontEnd(); duke@1: thEnd(); duke@1: trEnd(); duke@1: } duke@1: duke@1: /** duke@1: * Print table header end tags in inherited tables for column and row. duke@1: */ duke@1: public void tableInheritedHeaderEnd() { duke@1: thEnd(); duke@1: trEnd(); duke@1: } duke@1: duke@1: /** duke@1: * Print the summary table row cell attribute width. duke@1: * duke@1: * @param width Width of the table cell. duke@1: */ duke@1: public void summaryRow(int width) { duke@1: if (width != 0) { duke@1: tdWidth(width + "%"); duke@1: } else { duke@1: td(); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Print the summary table row cell end tag. duke@1: */ duke@1: public void summaryRowEnd() { duke@1: tdEnd(); duke@1: } duke@1: duke@1: /** jjg@1326: * Print the heading in Html {@literal

    } format. duke@1: * duke@1: * @param str The Header string. duke@1: */ duke@1: public void printIndexHeading(String str) { duke@1: h2(); duke@1: print(str); duke@1: h2End(); duke@1: } duke@1: duke@1: /** duke@1: * Print Html tag <FRAMESET=arg>. duke@1: * duke@1: * @param arg Argument for the tag. duke@1: */ duke@1: public void frameSet(String arg) { duke@1: println(""); duke@1: } duke@1: duke@1: /** duke@1: * Print Html closing tag </FRAMESET>. duke@1: */ duke@1: public void frameSetEnd() { duke@1: println(""); duke@1: } duke@1: duke@1: /** duke@1: * Print Html tag <FRAME=arg>. duke@1: * duke@1: * @param arg Argument for the tag. duke@1: */ duke@1: public void frame(String arg) { duke@1: println(""); duke@1: } duke@1: duke@1: /** duke@1: * Print Html closing tag </FRAME>. duke@1: */ duke@1: public void frameEnd() { duke@1: println(""); duke@1: } duke@1: duke@1: /** duke@1: * Return path to the class page for a classdoc. For example, the class duke@1: * name is "java.lang.Object" and if the current file getting generated is duke@1: * "java/io/File.html", then the path string to the class, returned is duke@1: * "../../java/lang.Object.html". duke@1: * duke@1: * @param cd Class to which the path is requested. duke@1: */ duke@1: protected String pathToClass(ClassDoc cd) { duke@1: return pathString(cd.containingPackage(), cd.name() + ".html"); duke@1: } duke@1: duke@1: /** duke@1: * Return the path to the class page for a classdoc. Works same as duke@1: * {@link #pathToClass(ClassDoc)}. duke@1: * duke@1: * @param cd Class to which the path is requested. duke@1: * @param name Name of the file(doesn't include path). duke@1: */ duke@1: protected String pathString(ClassDoc cd, String name) { duke@1: return pathString(cd.containingPackage(), name); duke@1: } duke@1: duke@1: /** duke@1: * Return path to the given file name in the given package. So if the name duke@1: * passed is "Object.html" and the name of the package is "java.lang", and duke@1: * if the relative path is "../.." then returned string will be duke@1: * "../../java/lang/Object.html" duke@1: * duke@1: * @param pd Package in which the file name is assumed to be. duke@1: * @param name File name, to which path string is. duke@1: */ duke@1: protected String pathString(PackageDoc pd, String name) { duke@1: StringBuffer buf = new StringBuffer(relativePath); duke@1: buf.append(DirectoryManager.getPathToPackage(pd, name)); duke@1: return buf.toString(); duke@1: } duke@1: duke@1: /** duke@1: * Print the link to the given package. duke@1: * duke@1: * @param pkg the package to link to. duke@1: * @param label the label for the link. bpatel@182: * @param isStrong true if the label should be strong. duke@1: */ bpatel@182: public void printPackageLink(PackageDoc pkg, String label, boolean isStrong) { bpatel@766: print(getPackageLinkString(pkg, label, isStrong)); duke@1: } duke@1: duke@1: /** duke@1: * Print the link to the given package. duke@1: * duke@1: * @param pkg the package to link to. duke@1: * @param label the label for the link. bpatel@182: * @param isStrong true if the label should be strong. duke@1: * @param style the font of the package link label. duke@1: */ bpatel@182: public void printPackageLink(PackageDoc pkg, String label, boolean isStrong, duke@1: String style) { bpatel@766: print(getPackageLinkString(pkg, label, isStrong, style)); duke@1: } duke@1: duke@1: /** duke@1: * Return the link to the given package. duke@1: * duke@1: * @param pkg the package to link to. duke@1: * @param label the label for the link. bpatel@182: * @param isStrong true if the label should be strong. duke@1: * @return the link to the given package. duke@1: */ bpatel@766: public String getPackageLinkString(PackageDoc pkg, String label, bpatel@182: boolean isStrong) { bpatel@766: return getPackageLinkString(pkg, label, isStrong, ""); duke@1: } duke@1: duke@1: /** duke@1: * Return the link to the given package. duke@1: * duke@1: * @param pkg the package to link to. duke@1: * @param label the label for the link. bpatel@182: * @param isStrong true if the label should be strong. duke@1: * @param style the font of the package link label. duke@1: * @return the link to the given package. duke@1: */ bpatel@766: public String getPackageLinkString(PackageDoc pkg, String label, boolean isStrong, duke@1: String style) { duke@1: boolean included = pkg != null && pkg.isIncluded(); duke@1: if (! included) { duke@1: PackageDoc[] packages = configuration.packages; duke@1: for (int i = 0; i < packages.length; i++) { duke@1: if (packages[i].equals(pkg)) { duke@1: included = true; duke@1: break; duke@1: } duke@1: } duke@1: } duke@1: if (included || pkg == null) { bpatel@766: return getHyperLinkString(pathString(pkg, "package-summary.html"), bpatel@182: "", label, isStrong, style); duke@1: } else { duke@1: String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg)); duke@1: if (crossPkgLink != null) { bpatel@766: return getHyperLinkString(crossPkgLink, "", label, isStrong, style); bpatel@766: } else { bpatel@766: return label; bpatel@766: } bpatel@766: } bpatel@766: } bpatel@766: bpatel@766: /** bpatel@766: * Return the link to the given package. bpatel@766: * bpatel@766: * @param pkg the package to link to. bpatel@766: * @param label the label for the link. bpatel@766: * @return a content tree for the package link. bpatel@766: */ bpatel@766: public Content getPackageLink(PackageDoc pkg, Content label) { bpatel@766: boolean included = pkg != null && pkg.isIncluded(); bpatel@766: if (! included) { bpatel@766: PackageDoc[] packages = configuration.packages; bpatel@766: for (int i = 0; i < packages.length; i++) { bpatel@766: if (packages[i].equals(pkg)) { bpatel@766: included = true; bpatel@766: break; bpatel@766: } bpatel@766: } bpatel@766: } bpatel@766: if (included || pkg == null) { bpatel@766: return getHyperLink(pathString(pkg, "package-summary.html"), bpatel@766: "", label); bpatel@766: } else { bpatel@766: String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg)); bpatel@766: if (crossPkgLink != null) { bpatel@766: return getHyperLink(crossPkgLink, "", label); duke@1: } else { duke@1: return label; duke@1: } duke@1: } duke@1: } duke@1: duke@1: public String italicsClassName(ClassDoc cd, boolean qual) { duke@1: String name = (qual)? cd.qualifiedName(): cd.name(); duke@1: return (cd.isInterface())? italicsText(name): name; duke@1: } duke@1: duke@1: public void printSrcLink(ProgramElementDoc d, String label) { duke@1: if (d == null) { duke@1: return; duke@1: } duke@1: ClassDoc cd = d.containingClass(); duke@1: if (cd == null) { duke@1: //d must be a class doc since in has no containing class. duke@1: cd = (ClassDoc) d; duke@1: } duke@1: String href = relativePath + DocletConstants.SOURCE_OUTPUT_DIR_NAME duke@1: + DirectoryManager.getDirectoryPath(cd.containingPackage()) duke@1: + cd.name() + ".html#" + SourceToHTMLConverter.getAnchorName(d); duke@1: printHyperLink(href, "", label, true); duke@1: } duke@1: duke@1: /** bpatel@766: * Add the link to the content tree. bpatel@766: * bpatel@766: * @param doc program element doc for which the link will be added bpatel@766: * @param label label for the link bpatel@766: * @param htmltree the content tree to which the link will be added bpatel@766: */ bpatel@766: public void addSrcLink(ProgramElementDoc doc, Content label, Content htmltree) { bpatel@766: if (doc == null) { bpatel@766: return; bpatel@766: } bpatel@766: ClassDoc cd = doc.containingClass(); bpatel@766: if (cd == null) { bpatel@766: //d must be a class doc since in has no containing class. bpatel@766: cd = (ClassDoc) doc; bpatel@766: } bpatel@766: String href = relativePath + DocletConstants.SOURCE_OUTPUT_DIR_NAME bpatel@766: + DirectoryManager.getDirectoryPath(cd.containingPackage()) bpatel@766: + cd.name() + ".html#" + SourceToHTMLConverter.getAnchorName(doc); bpatel@766: Content linkContent = getHyperLink(href, "", label, "", ""); bpatel@766: htmltree.addContent(linkContent); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Return the link to the given class. duke@1: * duke@1: * @param linkInfo the information about the link. duke@1: * duke@1: * @return the link for the given class. duke@1: */ duke@1: public String getLink(LinkInfoImpl linkInfo) { duke@1: LinkFactoryImpl factory = new LinkFactoryImpl(this); duke@1: String link = ((LinkOutputImpl) factory.getLinkOutput(linkInfo)).toString(); duke@1: displayLength += linkInfo.displayLength; duke@1: return link; duke@1: } duke@1: duke@1: /** duke@1: * Return the type parameters for the given class. duke@1: * duke@1: * @param linkInfo the information about the link. duke@1: * @return the type for the given class. duke@1: */ duke@1: public String getTypeParameterLinks(LinkInfoImpl linkInfo) { duke@1: LinkFactoryImpl factory = new LinkFactoryImpl(this); duke@1: return ((LinkOutputImpl) duke@1: factory.getTypeParameterLinks(linkInfo, false)).toString(); duke@1: } duke@1: duke@1: /** duke@1: * Print the link to the given class. duke@1: */ duke@1: public void printLink(LinkInfoImpl linkInfo) { duke@1: print(getLink(linkInfo)); duke@1: } duke@1: duke@1: /************************************************************* duke@1: * Return a class cross link to external class documentation. duke@1: * The name must be fully qualified to determine which package duke@1: * the class is in. The -link option does not allow users to duke@1: * link to external classes in the "default" package. duke@1: * duke@1: * @param qualifiedClassName the qualified name of the external class. duke@1: * @param refMemName the name of the member being referenced. This should duke@1: * be null or empty string if no member is being referenced. duke@1: * @param label the label for the external link. bpatel@182: * @param strong true if the link should be strong. duke@1: * @param style the style of the link. duke@1: * @param code true if the label should be code font. duke@1: */ duke@1: public String getCrossClassLink(String qualifiedClassName, String refMemName, bpatel@182: String label, boolean strong, String style, duke@1: boolean code) { duke@1: String className = "", duke@1: packageName = qualifiedClassName == null ? "" : qualifiedClassName; duke@1: int periodIndex; duke@1: while((periodIndex = packageName.lastIndexOf('.')) != -1) { duke@1: className = packageName.substring(periodIndex + 1, packageName.length()) + duke@1: (className.length() > 0 ? "." + className : ""); duke@1: String defaultLabel = code ? getCode() + className + getCodeEnd() : className; duke@1: packageName = packageName.substring(0, periodIndex); duke@1: if (getCrossPackageLink(packageName) != null) { duke@1: //The package exists in external documentation, so link to the external duke@1: //class (assuming that it exists). This is definitely a limitation of duke@1: //the -link option. There are ways to determine if an external package duke@1: //exists, but no way to determine if the external class exists. We just duke@1: //have to assume that it does. bpatel@766: return getHyperLinkString( duke@1: configuration.extern.getExternalLink(packageName, relativePath, duke@1: className + ".html?is-external=true"), duke@1: refMemName == null ? "" : refMemName, duke@1: label == null || label.length() == 0 ? defaultLabel : label, bpatel@182: strong, style, duke@1: configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName), duke@1: ""); duke@1: } duke@1: } duke@1: return null; duke@1: } duke@1: duke@1: public boolean isClassLinkable(ClassDoc cd) { duke@1: if (cd.isIncluded()) { duke@1: return configuration.isGeneratedDoc(cd); duke@1: } duke@1: return configuration.extern.isExternal(cd); duke@1: } duke@1: duke@1: public String getCrossPackageLink(String pkgName) { duke@1: return configuration.extern.getExternalLink(pkgName, relativePath, duke@1: "package-summary.html?is-external=true"); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Get the class link. bpatel@766: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param cd the class doc to link to bpatel@766: * @return a content tree for the link bpatel@766: */ bpatel@766: public Content getQualifiedClassLink(int context, ClassDoc cd) { bpatel@766: return new RawHtml(getLink(new LinkInfoImpl(context, cd, bpatel@766: configuration.getClassName(cd), ""))); duke@1: } duke@1: duke@1: /** bpatel@766: * Add the class link. bpatel@766: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param cd the class doc to link to bpatel@766: * @param contentTree the content tree to which the link will be added duke@1: */ bpatel@766: public void addPreQualifiedClassLink(int context, ClassDoc cd, Content contentTree) { bpatel@766: addPreQualifiedClassLink(context, cd, false, contentTree); duke@1: } duke@1: duke@1: /** duke@1: * Retrieve the class link with the package portion of the label in duke@1: * plain text. If the qualifier is excluded, it willnot be included in the duke@1: * link label. duke@1: * duke@1: * @param cd the class to link to. bpatel@182: * @param isStrong true if the link should be strong. duke@1: * @return the link with the package portion of the label in plain text. duke@1: */ duke@1: public String getPreQualifiedClassLink(int context, bpatel@182: ClassDoc cd, boolean isStrong) { duke@1: String classlink = ""; duke@1: PackageDoc pd = cd.containingPackage(); duke@1: if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) { duke@1: classlink = getPkgName(cd); duke@1: } bpatel@182: classlink += getLink(new LinkInfoImpl(context, cd, cd.name(), isStrong)); duke@1: return classlink; duke@1: } duke@1: bpatel@766: /** bpatel@766: * Add the class link with the package portion of the label in bpatel@766: * plain text. If the qualifier is excluded, it will not be included in the bpatel@766: * link label. bpatel@766: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param cd the class to link to bpatel@766: * @param isStrong true if the link should be strong bpatel@766: * @param contentTree the content tree to which the link with be added bpatel@766: */ bpatel@766: public void addPreQualifiedClassLink(int context, bpatel@766: ClassDoc cd, boolean isStrong, Content contentTree) { bpatel@766: PackageDoc pd = cd.containingPackage(); bpatel@766: if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) { bpatel@766: contentTree.addContent(getPkgName(cd)); bpatel@766: } bpatel@766: contentTree.addContent(new RawHtml(getLink(new LinkInfoImpl( bpatel@766: context, cd, cd.name(), isStrong)))); bpatel@766: } duke@1: duke@1: /** bpatel@766: * Add the class link, with only class name as the strong link and prefixing duke@1: * plain package name. bpatel@766: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param cd the class to link to bpatel@766: * @param contentTree the content tree to which the link with be added duke@1: */ bpatel@766: public void addPreQualifiedStrongClassLink(int context, ClassDoc cd, Content contentTree) { bpatel@766: addPreQualifiedClassLink(context, cd, true, contentTree); duke@1: } duke@1: duke@1: public void printText(String key) { duke@1: print(configuration.getText(key)); duke@1: } duke@1: duke@1: public void printText(String key, String a1) { duke@1: print(configuration.getText(key, a1)); duke@1: } duke@1: duke@1: public void printText(String key, String a1, String a2) { duke@1: print(configuration.getText(key, a1, a2)); duke@1: } duke@1: bpatel@182: public void strongText(String key) { bpatel@182: strong(configuration.getText(key)); duke@1: } duke@1: bpatel@182: public void strongText(String key, String a1) { bpatel@182: strong(configuration.getText(key, a1)); duke@1: } duke@1: bpatel@182: public void strongText(String key, String a1, String a2) { bpatel@182: strong(configuration.getText(key, a1, a2)); duke@1: } duke@1: duke@1: /** bpatel@766: * Get the link for the given member. duke@1: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param doc the member being linked to bpatel@766: * @param label the label for the link bpatel@766: * @return a content tree for the doc link duke@1: */ bpatel@766: public Content getDocLink(int context, MemberDoc doc, String label) { bpatel@766: return getDocLink(context, doc.containingClass(), doc, label); duke@1: } duke@1: duke@1: /** duke@1: * Print the link for the given member. duke@1: * duke@1: * @param context the id of the context where the link will be printed. duke@1: * @param classDoc the classDoc that we should link to. This is not duke@1: * necessarily equal to doc.containingClass(). We may be duke@1: * inheriting comments. duke@1: * @param doc the member being linked to. duke@1: * @param label the label for the link. bpatel@182: * @param strong true if the link should be strong. duke@1: */ duke@1: public void printDocLink(int context, ClassDoc classDoc, MemberDoc doc, bpatel@182: String label, boolean strong) { bpatel@182: print(getDocLink(context, classDoc, doc, label, strong)); duke@1: } duke@1: duke@1: /** duke@1: * Return the link for the given member. duke@1: * duke@1: * @param context the id of the context where the link will be printed. duke@1: * @param doc the member being linked to. duke@1: * @param label the label for the link. bpatel@182: * @param strong true if the link should be strong. duke@1: * @return the link for the given member. duke@1: */ duke@1: public String getDocLink(int context, MemberDoc doc, String label, bpatel@182: boolean strong) { bpatel@182: return getDocLink(context, doc.containingClass(), doc, label, strong); duke@1: } duke@1: duke@1: /** duke@1: * Return the link for the given member. duke@1: * duke@1: * @param context the id of the context where the link will be printed. duke@1: * @param classDoc the classDoc that we should link to. This is not duke@1: * necessarily equal to doc.containingClass(). We may be duke@1: * inheriting comments. duke@1: * @param doc the member being linked to. duke@1: * @param label the label for the link. bpatel@182: * @param strong true if the link should be strong. duke@1: * @return the link for the given member. duke@1: */ duke@1: public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc, bpatel@182: String label, boolean strong) { duke@1: if (! (doc.isIncluded() || duke@1: Util.isLinkable(classDoc, configuration()))) { duke@1: return label; duke@1: } else if (doc instanceof ExecutableMemberDoc) { duke@1: ExecutableMemberDoc emd = (ExecutableMemberDoc)doc; duke@1: return getLink(new LinkInfoImpl(context, classDoc, bpatel@182: getAnchor(emd), label, strong)); duke@1: } else if (doc instanceof MemberDoc) { duke@1: return getLink(new LinkInfoImpl(context, classDoc, bpatel@182: doc.name(), label, strong)); duke@1: } else { duke@1: return label; duke@1: } duke@1: } duke@1: bpatel@766: /** bpatel@766: * Return the link for the given member. bpatel@766: * bpatel@766: * @param context the id of the context where the link will be added bpatel@766: * @param classDoc the classDoc that we should link to. This is not bpatel@766: * necessarily equal to doc.containingClass(). We may be bpatel@766: * inheriting comments bpatel@766: * @param doc the member being linked to bpatel@766: * @param label the label for the link bpatel@766: * @return the link for the given member bpatel@766: */ bpatel@766: public Content getDocLink(int context, ClassDoc classDoc, MemberDoc doc, bpatel@766: String label) { bpatel@766: if (! (doc.isIncluded() || bpatel@766: Util.isLinkable(classDoc, configuration()))) { bpatel@766: return new StringContent(label); bpatel@766: } else if (doc instanceof ExecutableMemberDoc) { bpatel@766: ExecutableMemberDoc emd = (ExecutableMemberDoc)doc; bpatel@766: return new RawHtml(getLink(new LinkInfoImpl(context, classDoc, bpatel@766: getAnchor(emd), label, false))); bpatel@766: } else if (doc instanceof MemberDoc) { bpatel@766: return new RawHtml(getLink(new LinkInfoImpl(context, classDoc, bpatel@766: doc.name(), label, false))); bpatel@766: } else { bpatel@766: return new StringContent(label); bpatel@766: } bpatel@766: } bpatel@766: duke@1: public void anchor(ExecutableMemberDoc emd) { duke@1: anchor(getAnchor(emd)); duke@1: } duke@1: duke@1: public String getAnchor(ExecutableMemberDoc emd) { duke@1: StringBuilder signature = new StringBuilder(emd.signature()); duke@1: StringBuilder signatureParsed = new StringBuilder(); duke@1: int counter = 0; duke@1: for (int i = 0; i < signature.length(); i++) { duke@1: char c = signature.charAt(i); duke@1: if (c == '<') { duke@1: counter++; duke@1: } else if (c == '>') { duke@1: counter--; duke@1: } else if (counter == 0) { duke@1: signatureParsed.append(c); duke@1: } duke@1: } duke@1: return emd.name() + signatureParsed.toString(); duke@1: } duke@1: duke@1: public String seeTagToString(SeeTag see) { duke@1: String tagName = see.name(); duke@1: if (! (tagName.startsWith("@link") || tagName.equals("@see"))) { duke@1: return ""; duke@1: } duke@1: StringBuffer result = new StringBuffer(); duke@1: boolean isplaintext = tagName.toLowerCase().equals("@linkplain"); duke@1: String label = see.label(); duke@1: label = (label.length() > 0)? duke@1: ((isplaintext) ? label : duke@1: getCode() + label + getCodeEnd()):""; duke@1: String seetext = replaceDocRootDir(see.text()); duke@1: duke@1: //Check if @see is an href or "string" duke@1: if (seetext.startsWith("<") || seetext.startsWith("\"")) { duke@1: result.append(seetext); duke@1: return result.toString(); duke@1: } duke@1: duke@1: //The text from the @see tag. We will output this text when a label is not specified. duke@1: String text = (isplaintext) ? seetext : getCode() + seetext + getCodeEnd(); duke@1: duke@1: ClassDoc refClass = see.referencedClass(); duke@1: String refClassName = see.referencedClassName(); duke@1: MemberDoc refMem = see.referencedMember(); duke@1: String refMemName = see.referencedMemberName(); duke@1: if (refClass == null) { duke@1: //@see is not referencing an included class duke@1: PackageDoc refPackage = see.referencedPackage(); duke@1: if (refPackage != null && refPackage.isIncluded()) { duke@1: //@see is referencing an included package duke@1: String packageName = isplaintext ? refPackage.name() : duke@1: getCode() + refPackage.name() + getCodeEnd(); bpatel@766: result.append(getPackageLinkString(refPackage, duke@1: label.length() == 0 ? packageName : label, false)); duke@1: } else { duke@1: //@see is not referencing an included class or package. Check for cross links. duke@1: String classCrossLink, packageCrossLink = getCrossPackageLink(refClassName); duke@1: if (packageCrossLink != null) { duke@1: //Package cross link found bpatel@766: result.append(getHyperLinkString(packageCrossLink, "", duke@1: (label.length() == 0)? text : label, false)); duke@1: } else if ((classCrossLink = getCrossClassLink(refClassName, duke@1: refMemName, label, false, "", ! isplaintext)) != null) { duke@1: //Class cross link found (possiblly to a member in the class) duke@1: result.append(classCrossLink); duke@1: } else { duke@1: //No cross link found so print warning duke@1: configuration.getDocletSpecificMsg().warning(see.position(), "doclet.see.class_or_package_not_found", duke@1: tagName, seetext); duke@1: result.append((label.length() == 0)? text: label); duke@1: } duke@1: } duke@1: } else if (refMemName == null) { duke@1: // Must be a class reference since refClass is not null and refMemName is null. duke@1: if (label.length() == 0) { duke@1: label = (isplaintext) ? refClass.name() : getCode() + refClass.name() + getCodeEnd(); duke@1: result.append(getLink(new LinkInfoImpl(refClass, label))); duke@1: } else { duke@1: result.append(getLink(new LinkInfoImpl(refClass, label))); duke@1: } duke@1: } else if (refMem == null) { duke@1: // Must be a member reference since refClass is not null and refMemName is not null. duke@1: // However, refMem is null, so this referenced member does not exist. duke@1: result.append((label.length() == 0)? text: label); duke@1: } else { duke@1: // Must be a member reference since refClass is not null and refMemName is not null. duke@1: // refMem is not null, so this @see tag must be referencing a valid member. duke@1: ClassDoc containing = refMem.containingClass(); duke@1: if (see.text().trim().startsWith("#") && duke@1: ! (containing.isPublic() || duke@1: Util.isLinkable(containing, configuration()))) { duke@1: // Since the link is relative and the holder is not even being duke@1: // documented, this must be an inherited link. Redirect it. duke@1: // The current class either overrides the referenced member or duke@1: // inherits it automatically. jjg@405: if (this instanceof ClassWriterImpl) { jjg@405: containing = ((ClassWriterImpl) this).getClassDoc(); jjg@405: } else if (!containing.isPublic()){ jjg@405: configuration.getDocletSpecificMsg().warning( jjg@405: see.position(), "doclet.see.class_or_package_not_accessible", jjg@405: tagName, containing.qualifiedName()); jjg@405: } else { jjg@405: configuration.getDocletSpecificMsg().warning( jjg@405: see.position(), "doclet.see.class_or_package_not_found", jjg@405: tagName, seetext); jjg@405: } duke@1: } duke@1: if (configuration.currentcd != containing) { duke@1: refMemName = containing.name() + "." + refMemName; duke@1: } duke@1: if (refMem instanceof ExecutableMemberDoc) { duke@1: if (refMemName.indexOf('(') < 0) { duke@1: refMemName += ((ExecutableMemberDoc)refMem).signature(); duke@1: } duke@1: } duke@1: text = (isplaintext) ? bpatel@981: refMemName : getCode() + Util.escapeHtmlChars(refMemName) + getCodeEnd(); duke@1: duke@1: result.append(getDocLink(LinkInfoImpl.CONTEXT_SEE_TAG, containing, duke@1: refMem, (label.length() == 0)? text: label, false)); duke@1: } duke@1: return result.toString(); duke@1: } duke@1: duke@1: public void printInlineComment(Doc doc, Tag tag) { duke@1: printCommentTags(doc, tag.inlineTags(), false, false); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Add the inline comment. bpatel@766: * bpatel@766: * @param doc the doc for which the inline comment will be added bpatel@766: * @param tag the inline tag to be added bpatel@766: * @param htmltree the content tree to which the comment will be added bpatel@766: */ bpatel@766: public void addInlineComment(Doc doc, Tag tag, Content htmltree) { bpatel@766: addCommentTags(doc, tag.inlineTags(), false, false, htmltree); bpatel@766: } bpatel@766: duke@1: public void printInlineDeprecatedComment(Doc doc, Tag tag) { duke@1: printCommentTags(doc, tag.inlineTags(), true, false); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Add the inline deprecated comment. bpatel@766: * bpatel@766: * @param doc the doc for which the inline deprecated comment will be added bpatel@766: * @param tag the inline tag to be added bpatel@766: * @param htmltree the content tree to which the comment will be added bpatel@766: */ bpatel@766: public void addInlineDeprecatedComment(Doc doc, Tag tag, Content htmltree) { bpatel@766: addCommentTags(doc, tag.inlineTags(), true, false, htmltree); bpatel@766: } bpatel@766: duke@1: public void printSummaryComment(Doc doc) { duke@1: printSummaryComment(doc, doc.firstSentenceTags()); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Adds the summary content. bpatel@766: * bpatel@766: * @param doc the doc for which the summary will be generated bpatel@766: * @param htmltree the documentation tree to which the summary will be added bpatel@766: */ bpatel@766: public void addSummaryComment(Doc doc, Content htmltree) { bpatel@766: addSummaryComment(doc, doc.firstSentenceTags(), htmltree); bpatel@766: } bpatel@766: duke@1: public void printSummaryComment(Doc doc, Tag[] firstSentenceTags) { duke@1: printCommentTags(doc, firstSentenceTags, false, true); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Adds the summary content. bpatel@766: * bpatel@766: * @param doc the doc for which the summary will be generated bpatel@766: * @param firstSentenceTags the first sentence tags for the doc bpatel@766: * @param htmltree the documentation tree to which the summary will be added bpatel@766: */ bpatel@766: public void addSummaryComment(Doc doc, Tag[] firstSentenceTags, Content htmltree) { bpatel@766: addCommentTags(doc, firstSentenceTags, false, true, htmltree); bpatel@766: } bpatel@766: duke@1: public void printSummaryDeprecatedComment(Doc doc) { duke@1: printCommentTags(doc, doc.firstSentenceTags(), true, true); duke@1: } duke@1: duke@1: public void printSummaryDeprecatedComment(Doc doc, Tag tag) { duke@1: printCommentTags(doc, tag.firstSentenceTags(), true, true); duke@1: } duke@1: bpatel@766: public void addSummaryDeprecatedComment(Doc doc, Tag tag, Content htmltree) { bpatel@766: addCommentTags(doc, tag.firstSentenceTags(), true, true, htmltree); bpatel@766: } bpatel@766: duke@1: public void printInlineComment(Doc doc) { duke@1: printCommentTags(doc, doc.inlineTags(), false, false); duke@1: p(); duke@1: } duke@1: bpatel@766: /** bpatel@766: * Adds the inline comment. bpatel@766: * bpatel@766: * @param doc the doc for which the inline comments will be generated bpatel@766: * @param htmltree the documentation tree to which the inline comments will be added bpatel@766: */ bpatel@766: public void addInlineComment(Doc doc, Content htmltree) { bpatel@766: addCommentTags(doc, doc.inlineTags(), false, false, htmltree); bpatel@766: } bpatel@766: duke@1: public void printInlineDeprecatedComment(Doc doc) { duke@1: printCommentTags(doc, doc.inlineTags(), true, false); duke@1: } duke@1: duke@1: private void printCommentTags(Doc doc, Tag[] tags, boolean depr, boolean first) { duke@1: if(configuration.nocomment){ duke@1: return; duke@1: } duke@1: if (depr) { duke@1: italic(); duke@1: } duke@1: String result = commentTagsToString(null, doc, tags, first); duke@1: print(result); duke@1: if (depr) { duke@1: italicEnd(); duke@1: } duke@1: if (tags.length == 0) { duke@1: space(); duke@1: } duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the comment tags. bpatel@766: * bpatel@766: * @param doc the doc for which the comment tags will be generated bpatel@766: * @param tags the first sentence tags for the doc bpatel@766: * @param depr true if it is deprecated bpatel@766: * @param first true if the first sentenge tags should be added bpatel@766: * @param htmltree the documentation tree to which the comment tags will be added bpatel@766: */ bpatel@766: private void addCommentTags(Doc doc, Tag[] tags, boolean depr, bpatel@766: boolean first, Content htmltree) { bpatel@766: if(configuration.nocomment){ bpatel@766: return; bpatel@766: } bpatel@766: Content div; bpatel@766: Content result = new RawHtml(commentTagsToString(null, doc, tags, first)); bpatel@766: if (depr) { bpatel@766: Content italic = HtmlTree.I(result); bpatel@766: div = HtmlTree.DIV(HtmlStyle.block, italic); bpatel@766: htmltree.addContent(div); bpatel@766: } bpatel@766: else { bpatel@766: div = HtmlTree.DIV(HtmlStyle.block, result); bpatel@766: htmltree.addContent(div); bpatel@766: } bpatel@766: if (tags.length == 0) { bpatel@766: htmltree.addContent(getSpace()); bpatel@766: } bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Converts inline tags and text to text strings, expanding the duke@1: * inline tags along the way. Called wherever text can contain duke@1: * an inline tag, such as in comments or in free-form text arguments duke@1: * to non-inline tags. duke@1: * duke@1: * @param holderTag specific tag where comment resides duke@1: * @param doc specific doc where comment resides duke@1: * @param tags array of text tags and inline tags (often alternating) duke@1: * present in the text of interest for this doc duke@1: * @param isFirstSentence true if text is first sentence duke@1: */ duke@1: public String commentTagsToString(Tag holderTag, Doc doc, Tag[] tags, duke@1: boolean isFirstSentence) { jjg@910: StringBuilder result = new StringBuilder(); bpatel@997: boolean textTagChange = false; duke@1: // Array of all possible inline tags for this javadoc run duke@1: configuration.tagletManager.checkTags(doc, tags, true); duke@1: for (int i = 0; i < tags.length; i++) { duke@1: Tag tagelem = tags[i]; duke@1: String tagName = tagelem.name(); duke@1: if (tagelem instanceof SeeTag) { duke@1: result.append(seeTagToString((SeeTag)tagelem)); duke@1: } else if (! tagName.equals("Text")) { duke@1: int originalLength = result.length(); duke@1: TagletOutput output = TagletWriter.getInlineTagOuput( duke@1: configuration.tagletManager, holderTag, jjg@74: tagelem, getTagletWriterInstance(isFirstSentence)); duke@1: result.append(output == null ? "" : output.toString()); duke@1: if (originalLength == 0 && isFirstSentence && tagelem.name().equals("@inheritDoc") && result.length() > 0) { duke@1: break; bpatel@997: } else if (configuration.docrootparent.length() > 0 && bpatel@997: tagelem.name().equals("@docRoot") && bpatel@997: ((tags[i + 1]).text()).startsWith("/..")) { bpatel@997: //If Xdocrootparent switch ON, set the flag to remove the /.. occurance after bpatel@997: //{@docRoot} tag in the very next Text tag. bpatel@997: textTagChange = true; bpatel@997: continue; duke@1: } else { bpatel@997: continue; duke@1: } duke@1: } else { bpatel@997: String text = tagelem.text(); bpatel@997: //If Xdocrootparent switch ON, remove the /.. occurance after {@docRoot} tag. bpatel@997: if (textTagChange) { bpatel@997: text = text.replaceFirst("/..", ""); bpatel@997: textTagChange = false; bpatel@997: } duke@1: //This is just a regular text tag. The text may contain html links () duke@1: //or inline tag {@docRoot}, which will be handled as special cases. bpatel@997: text = redirectRelativeLinks(tagelem.holder(), text); duke@1: duke@1: // Replace @docRoot only if not represented by an instance of DocRootTaglet, duke@1: // that is, only if it was not present in a source file doc comment. duke@1: // This happens when inserted by the doclet (a few lines duke@1: // above in this method). [It might also happen when passed in on the command duke@1: // line as a text argument to an option (like -header).] duke@1: text = replaceDocRootDir(text); duke@1: if (isFirstSentence) { duke@1: text = removeNonInlineHtmlTags(text); duke@1: } duke@1: StringTokenizer lines = new StringTokenizer(text, "\r\n", true); duke@1: StringBuffer textBuff = new StringBuffer(); duke@1: while (lines.hasMoreTokens()) { jjg@910: StringBuilder line = new StringBuilder(lines.nextToken()); duke@1: Util.replaceTabs(configuration.sourcetab, line); duke@1: textBuff.append(line.toString()); duke@1: } duke@1: result.append(textBuff); duke@1: } duke@1: } duke@1: return result.toString(); duke@1: } duke@1: duke@1: /** duke@1: * Return true if relative links should not be redirected. duke@1: * duke@1: * @return Return true if a relative link should not be redirected. duke@1: */ duke@1: private boolean shouldNotRedirectRelativeLinks() { duke@1: return this instanceof AnnotationTypeWriter || duke@1: this instanceof ClassWriter || duke@1: this instanceof PackageSummaryWriter; duke@1: } duke@1: duke@1: /** duke@1: * Suppose a piece of documentation has a relative link. When you copy duke@1: * that documetation to another place such as the index or class-use page, duke@1: * that relative link will no longer work. We should redirect those links duke@1: * so that they will work again. duke@1: *

    duke@1: * Here is the algorithm used to fix the link: duke@1: *

    jjg@1326: * {@literal => docRoot + + } duke@1: *

    duke@1: * For example, suppose com.sun.javadoc.RootDoc has this link: jjg@1326: * {@literal The package Page } duke@1: *

    duke@1: * If this link appeared in the index, we would redirect duke@1: * the link like this: duke@1: * jjg@1326: * {@literal The package Page} duke@1: * duke@1: * @param doc the Doc object whose documentation is being written. duke@1: * @param text the text being written. duke@1: * duke@1: * @return the text, with all the relative links redirected to work. duke@1: */ duke@1: private String redirectRelativeLinks(Doc doc, String text) { duke@1: if (doc == null || shouldNotRedirectRelativeLinks()) { duke@1: return text; duke@1: } duke@1: duke@1: String redirectPathFromRoot; duke@1: if (doc instanceof ClassDoc) { duke@1: redirectPathFromRoot = DirectoryManager.getDirectoryPath(((ClassDoc) doc).containingPackage()); duke@1: } else if (doc instanceof MemberDoc) { duke@1: redirectPathFromRoot = DirectoryManager.getDirectoryPath(((MemberDoc) doc).containingPackage()); duke@1: } else if (doc instanceof PackageDoc) { duke@1: redirectPathFromRoot = DirectoryManager.getDirectoryPath((PackageDoc) doc); duke@1: } else { duke@1: return text; duke@1: } duke@1: bpatel@766: if (! redirectPathFromRoot.endsWith(DirectoryManager.URL_FILE_SEPARATOR)) { bpatel@766: redirectPathFromRoot += DirectoryManager.URL_FILE_SEPARATOR; duke@1: } duke@1: duke@1: //Redirect all relative links. duke@1: int end, begin = text.toLowerCase().indexOf("= 0){ duke@1: StringBuffer textBuff = new StringBuffer(text); duke@1: duke@1: while(begin >=0){ duke@1: if (textBuff.length() > begin + 2 && ! Character.isWhitespace(textBuff.charAt(begin+2))) { duke@1: begin = textBuff.toString().toLowerCase().indexOf("", begin +1); duke@1: if(begin == 0){ duke@1: //Link has no equal symbol. duke@1: configuration.root.printWarning( duke@1: doc.position(), duke@1: configuration.getText("doclet.malformed_html_link_tag", text)); duke@1: break; duke@1: } duke@1: if (end == -1) { duke@1: //Break without warning. This tag is not necessarily malformed. The text duke@1: //might be missing '>' character because the href has an inline tag. duke@1: break; duke@1: } duke@1: if(textBuff.substring(begin, end).indexOf("\"") != -1){ duke@1: begin = textBuff.indexOf("\"", begin) + 1; duke@1: end = textBuff.indexOf("\"", begin +1); duke@1: if(begin == 0 || end == -1){ duke@1: //Link is missing a quote. duke@1: break; duke@1: } duke@1: } duke@1: String relativeLink = textBuff.substring(begin, end); duke@1: if(!(relativeLink.toLowerCase().startsWith("mailto:") || duke@1: relativeLink.toLowerCase().startsWith("http:") || duke@1: relativeLink.toLowerCase().startsWith("https:") || duke@1: relativeLink.toLowerCase().startsWith("file:"))){ duke@1: relativeLink = "{@"+(new DocRootTaglet()).getName() + "}" duke@1: + redirectPathFromRoot duke@1: + relativeLink; duke@1: textBuff.replace(begin, end, relativeLink); duke@1: } duke@1: begin = textBuff.toString().toLowerCase().indexOf("", "", "

      ", "
    ", duke@1: "
    ", "
    ", "", "
    ", duke@1: "

    ", "", "
    ", "
    ", duke@1: "", "", "", "", duke@1: "", "", "

    ", "

    ", duke@1: "
  • ", "
  • ", "
    ", "
    ", duke@1: "", "", "
    ", "
    ", duke@1: "

    ", "

    ", "

    ", "

    ", duke@1: "

    ", "

    ", "

    ", "

    ", duke@1: "
    ", "
    ", "
    ", "
    ", duke@1: "
    ", "
    ", "", "", duke@1: "", "", "
    ", duke@1: "
    ", "
    ", duke@1: "
    ", "
    " duke@1: }; duke@1: for (int i = 0; i < noninlinetags.length; i++) { duke@1: text = replace(text, noninlinetags[i], ""); duke@1: } duke@1: return text; duke@1: } duke@1: duke@1: public String replace(String text, String tobe, String by) { duke@1: while (true) { duke@1: int startindex = text.indexOf(tobe); duke@1: if (startindex < 0) { duke@1: return text; duke@1: } duke@1: int endindex = startindex + tobe.length(); jjg@910: StringBuilder replaced = new StringBuilder(); duke@1: if (startindex > 0) { duke@1: replaced.append(text.substring(0, startindex)); duke@1: } duke@1: replaced.append(by); duke@1: if (text.length() > endindex) { duke@1: replaced.append(text.substring(endindex)); duke@1: } duke@1: text = replaced.toString(); duke@1: } duke@1: } duke@1: duke@1: public void printStyleSheetProperties() { duke@1: String filename = configuration.stylesheetfile; duke@1: if (filename.length() > 0) { duke@1: File stylefile = new File(filename); duke@1: String parent = stylefile.getParent(); duke@1: filename = (parent == null)? duke@1: filename: duke@1: filename.substring(parent.length() + 1); duke@1: } else { duke@1: filename = "stylesheet.css"; duke@1: } duke@1: filename = relativePath + filename; duke@1: link("REL =\"stylesheet\" TYPE=\"text/css\" HREF=\"" + duke@1: filename + "\" " + "TITLE=\"Style\""); duke@1: } duke@1: duke@1: /** bpatel@766: * Returns a link to the stylesheet file. bpatel@766: * bpatel@766: * @return an HtmlTree for the lINK tag which provides the stylesheet location bpatel@766: */ bpatel@766: public HtmlTree getStyleSheetProperties() { bpatel@766: String filename = configuration.stylesheetfile; bpatel@766: if (filename.length() > 0) { bpatel@766: File stylefile = new File(filename); bpatel@766: String parent = stylefile.getParent(); bpatel@766: filename = (parent == null)? bpatel@766: filename: bpatel@766: filename.substring(parent.length() + 1); bpatel@766: } else { bpatel@766: filename = "stylesheet.css"; bpatel@766: } bpatel@766: filename = relativePath + filename; bpatel@766: HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", filename, "Style"); bpatel@766: return link; bpatel@766: } bpatel@766: bpatel@766: /** jjh@972: * According to jjh@972: * The Java™ Language Specification, jjh@972: * all the outer classes and static nested classes are core classes. duke@1: */ duke@1: public boolean isCoreClass(ClassDoc cd) { duke@1: return cd.containingClass() == null || cd.isStatic(); duke@1: } duke@1: duke@1: /** duke@1: * Write the annotatation types for the given packageDoc. duke@1: * duke@1: * @param packageDoc the package to write annotations for. duke@1: */ duke@1: public void writeAnnotationInfo(PackageDoc packageDoc) { duke@1: writeAnnotationInfo(packageDoc, packageDoc.annotations()); duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the annotatation types for the given packageDoc. bpatel@766: * bpatel@766: * @param packageDoc the package to write annotations for. bpatel@766: * @param htmltree the documentation tree to which the annotation info will be bpatel@766: * added bpatel@766: */ bpatel@766: public void addAnnotationInfo(PackageDoc packageDoc, Content htmltree) { bpatel@766: addAnnotationInfo(packageDoc, packageDoc.annotations(), htmltree); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Write the annotatation types for the given doc. duke@1: * duke@1: * @param doc the doc to write annotations for. duke@1: */ duke@1: public void writeAnnotationInfo(ProgramElementDoc doc) { duke@1: writeAnnotationInfo(doc, doc.annotations()); duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the annotatation types for the given doc. bpatel@766: * bpatel@766: * @param packageDoc the package to write annotations for bpatel@766: * @param htmltree the content tree to which the annotation types will be added bpatel@766: */ bpatel@766: public void addAnnotationInfo(ProgramElementDoc doc, Content htmltree) { bpatel@766: addAnnotationInfo(doc, doc.annotations(), htmltree); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Write the annotatation types for the given doc and parameter. duke@1: * duke@1: * @param indent the number of spaced to indent the parameters. duke@1: * @param doc the doc to write annotations for. duke@1: * @param param the parameter to write annotations for. duke@1: */ duke@1: public boolean writeAnnotationInfo(int indent, Doc doc, Parameter param) { duke@1: return writeAnnotationInfo(indent, doc, param.annotations(), false); duke@1: } duke@1: duke@1: /** bpatel@766: * Add the annotatation types for the given doc and parameter. bpatel@766: * bpatel@766: * @param indent the number of spaces to indent the parameters. bpatel@766: * @param doc the doc to write annotations for. bpatel@766: * @param param the parameter to write annotations for. bpatel@766: * @param tree the content tree to which the annotation types will be added bpatel@766: */ bpatel@766: public boolean addAnnotationInfo(int indent, Doc doc, Parameter param, bpatel@766: Content tree) { bpatel@766: return addAnnotationInfo(indent, doc, param.annotations(), false, tree); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Write the annotatation types for the given doc. duke@1: * duke@1: * @param doc the doc to write annotations for. duke@1: * @param descList the array of {@link AnnotationDesc}. duke@1: */ duke@1: private void writeAnnotationInfo(Doc doc, AnnotationDesc[] descList) { duke@1: writeAnnotationInfo(0, doc, descList, true); duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the annotatation types for the given doc. bpatel@766: * bpatel@766: * @param doc the doc to write annotations for. bpatel@766: * @param descList the array of {@link AnnotationDesc}. bpatel@766: * @param htmltree the documentation tree to which the annotation info will be bpatel@766: * added bpatel@766: */ bpatel@766: private void addAnnotationInfo(Doc doc, AnnotationDesc[] descList, bpatel@766: Content htmltree) { bpatel@766: addAnnotationInfo(0, doc, descList, true, htmltree); bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Write the annotatation types for the given doc. duke@1: * duke@1: * @param indent the number of extra spaces to indent the annotations. duke@1: * @param doc the doc to write annotations for. duke@1: * @param descList the array of {@link AnnotationDesc}. duke@1: */ duke@1: private boolean writeAnnotationInfo(int indent, Doc doc, AnnotationDesc[] descList, boolean lineBreak) { mcimadamore@184: List annotations = getAnnotations(indent, descList, lineBreak); duke@1: if (annotations.size() == 0) { duke@1: return false; duke@1: } duke@1: fontNoNewLine("-1"); mcimadamore@184: for (Iterator iter = annotations.iterator(); iter.hasNext();) { mcimadamore@184: print(iter.next()); duke@1: } duke@1: fontEnd(); duke@1: return true; duke@1: } duke@1: duke@1: /** bpatel@766: * Adds the annotatation types for the given doc. bpatel@766: * bpatel@766: * @param indent the number of extra spaces to indent the annotations. bpatel@766: * @param doc the doc to write annotations for. bpatel@766: * @param descList the array of {@link AnnotationDesc}. bpatel@766: * @param htmltree the documentation tree to which the annotation info will be bpatel@766: * added bpatel@766: */ bpatel@766: private boolean addAnnotationInfo(int indent, Doc doc, bpatel@766: AnnotationDesc[] descList, boolean lineBreak, Content htmltree) { bpatel@766: List annotations = getAnnotations(indent, descList, lineBreak); bpatel@766: if (annotations.size() == 0) { bpatel@766: return false; bpatel@766: } bpatel@766: Content annotationContent; bpatel@766: for (Iterator iter = annotations.iterator(); iter.hasNext();) { bpatel@766: annotationContent = new RawHtml(iter.next()); bpatel@766: htmltree.addContent(annotationContent); bpatel@766: } bpatel@766: return true; bpatel@766: } bpatel@766: bpatel@766: /** duke@1: * Return the string representations of the annotation types for duke@1: * the given doc. duke@1: * duke@1: * @param indent the number of extra spaces to indent the annotations. duke@1: * @param descList the array of {@link AnnotationDesc}. duke@1: * @param linkBreak if true, add new line between each member value. duke@1: * @return an array of strings representing the annotations being duke@1: * documented. duke@1: */ jjg@74: private List getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) { jjg@74: List results = new ArrayList(); duke@1: StringBuffer annotation; duke@1: for (int i = 0; i < descList.length; i++) { duke@1: AnnotationTypeDoc annotationDoc = descList[i].annotationType(); duke@1: if (! Util.isDocumentedAnnotation(annotationDoc)){ duke@1: continue; duke@1: } duke@1: annotation = new StringBuffer(); duke@1: LinkInfoImpl linkInfo = new LinkInfoImpl( duke@1: LinkInfoImpl.CONTEXT_ANNOTATION, annotationDoc); duke@1: linkInfo.label = "@" + annotationDoc.name(); duke@1: annotation.append(getLink(linkInfo)); duke@1: AnnotationDesc.ElementValuePair[] pairs = descList[i].elementValues(); duke@1: if (pairs.length > 0) { duke@1: annotation.append('('); duke@1: for (int j = 0; j < pairs.length; j++) { duke@1: if (j > 0) { duke@1: annotation.append(","); duke@1: if (linkBreak) { duke@1: annotation.append(DocletConstants.NL); duke@1: int spaces = annotationDoc.name().length() + 2; duke@1: for (int k = 0; k < (spaces + indent); k++) { duke@1: annotation.append(' '); duke@1: } duke@1: } duke@1: } duke@1: annotation.append(getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION, duke@1: pairs[j].element(), pairs[j].element().name(), false)); duke@1: annotation.append('='); duke@1: AnnotationValue annotationValue = pairs[j].value(); jjg@74: List annotationTypeValues = new ArrayList(); duke@1: if (annotationValue.value() instanceof AnnotationValue[]) { duke@1: AnnotationValue[] annotationArray = duke@1: (AnnotationValue[]) annotationValue.value(); duke@1: for (int k = 0; k < annotationArray.length; k++) { duke@1: annotationTypeValues.add(annotationArray[k]); duke@1: } duke@1: } else { duke@1: annotationTypeValues.add(annotationValue); duke@1: } duke@1: annotation.append(annotationTypeValues.size() == 1 ? "" : "{"); mcimadamore@184: for (Iterator iter = annotationTypeValues.iterator(); iter.hasNext(); ) { mcimadamore@184: annotation.append(annotationValueToString(iter.next())); duke@1: annotation.append(iter.hasNext() ? "," : ""); duke@1: } duke@1: annotation.append(annotationTypeValues.size() == 1 ? "" : "}"); duke@1: } duke@1: annotation.append(")"); duke@1: } duke@1: annotation.append(linkBreak ? DocletConstants.NL : ""); duke@1: results.add(annotation.toString()); duke@1: } duke@1: return results; duke@1: } duke@1: duke@1: private String annotationValueToString(AnnotationValue annotationValue) { duke@1: if (annotationValue.value() instanceof Type) { duke@1: Type type = (Type) annotationValue.value(); duke@1: if (type.asClassDoc() != null) { duke@1: LinkInfoImpl linkInfo = new LinkInfoImpl( duke@1: LinkInfoImpl.CONTEXT_ANNOTATION, type); duke@1: linkInfo.label = (type.asClassDoc().isIncluded() ? duke@1: type.typeName() : duke@1: type.qualifiedTypeName()) + type.dimension() + ".class"; duke@1: return getLink(linkInfo); duke@1: } else { duke@1: return type.typeName() + type.dimension() + ".class"; duke@1: } duke@1: } else if (annotationValue.value() instanceof AnnotationDesc) { mcimadamore@184: List list = getAnnotations(0, duke@1: new AnnotationDesc[]{(AnnotationDesc) annotationValue.value()}, duke@1: false); duke@1: StringBuffer buf = new StringBuffer(); mcimadamore@184: for (Iterator iter = list.iterator(); iter.hasNext(); ) { duke@1: buf.append(iter.next()); duke@1: } duke@1: return buf.toString(); duke@1: } else if (annotationValue.value() instanceof MemberDoc) { duke@1: return getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION, duke@1: (MemberDoc) annotationValue.value(), duke@1: ((MemberDoc) annotationValue.value()).name(), false); duke@1: } else { duke@1: return annotationValue.toString(); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Return the configuation for this doclet. duke@1: * duke@1: * @return the configuration for this doclet. duke@1: */ duke@1: public Configuration configuration() { duke@1: return configuration; duke@1: } duke@1: }