< prev index next >

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java

Print this page




 138      * Name of the file getting generated. If the file getting generated is
 139      * "java/lang/Object.html", then the filename is "Object.html".
 140      */
 141     public final DocPath filename;
 142 
 143     /**
 144      * The global configuration information for this run.
 145      */
 146     public final HtmlConfiguration configuration;
 147 
 148     protected final Utils utils;
 149 
 150     protected final Contents contents;
 151 
 152     protected final Messages messages;
 153 
 154     protected final Resources resources;
 155 
 156     protected final Links links;
 157 


 158     /**
 159      * To check whether annotation heading is printed or not.
 160      */
 161     protected boolean printedAnnotationHeading = false;
 162 
 163     /**
 164      * To check whether annotation field heading is printed or not.
 165      */
 166     protected boolean printedAnnotationFieldHeading = false;
 167 
 168     /**
 169      * To check whether the repeated annotations is documented or not.
 170      */
 171     private boolean isAnnotationDocumented = false;
 172 
 173     /**
 174      * To check whether the container annotations is documented or not.
 175      */
 176     private boolean isContainerDocumented = false;
 177 


 185     protected String winTitle;
 186 
 187     protected Script mainBodyScript;
 188 
 189     /**
 190      * Constructor to construct the HtmlStandardWriter object.
 191      *
 192      * @param configuration the configuration for this doclet
 193      * @param path the file to be generated.
 194      */
 195     public HtmlDocletWriter(HtmlConfiguration configuration, DocPath path) {
 196         this.configuration = configuration;
 197         this.contents = configuration.contents;
 198         this.messages = configuration.messages;
 199         this.resources = configuration.resources;
 200         this.links = new Links(path, configuration.htmlVersion);
 201         this.utils = configuration.utils;
 202         this.path = path;
 203         this.pathToRoot = path.parent().invert();
 204         this.filename = path.basename();

 205 
 206         messages.notice("doclet.Generating_0",
 207             DocFile.createFileForOutput(configuration, path).getPath());
 208     }
 209 
 210     /**
 211      * Replace {@docRoot} tag used in options that accept HTML text, such
 212      * as -header, -footer, -top and -bottom, and when converting a relative
 213      * HREF where commentTagsToString inserts a {@docRoot} where one was
 214      * missing.  (Also see DocRootTaglet for {@docRoot} tags in doc
 215      * comments.)
 216      * <p>
 217      * Replace {@docRoot} tag in htmlstr with the relative path to the
 218      * destination directory from the directory where the file is being
 219      * written, looping to handle all such tags in htmlstr.
 220      * <p>
 221      * For example, for "-d docs" and -header containing {@docRoot}, when
 222      * the HTML page for source file p/C1.java is being generated, the
 223      * {@docRoot} tag would be inserted into the header as "../",
 224      * the relative path from docs/p/ to docs/ (the document root).


 382      * @param label tag for the link
 383      * @param mdle the module being documented
 384      * @return a content for the target module packages link
 385      */
 386     public Content getTargetModulePackageLink(PackageElement pkg, String target,
 387             Content label, ModuleElement mdle) {
 388         return links.createLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
 389                 label, "", target);
 390     }
 391 
 392     /**
 393      * Get Module link, with target frame.
 394      *
 395      * @param target name of the target frame
 396      * @param label tag for the link
 397      * @param mdle the module being documented
 398      * @return a content for the target module link
 399      */
 400     public Content getTargetModuleLink(String target, Content label, ModuleElement mdle) {
 401         return links.createLink(pathToRoot.resolve(
 402                 DocPaths.moduleSummary(mdle)), label, "", target);
 403     }
 404 
 405     /**
 406      * Generates the HTML document tree and prints it out.
 407      *
 408      * @param metakeywords Array of String keywords for META tag. Each element
 409      *                     of the array is assigned to a separate META tag.
 410      *                     Pass in null for no array
 411      * @param includeScript true if printing windowtitle script
 412      *                      false for files that appear in the left-hand frames
 413      * @param body the body htmltree to be included in the document
 414      * @throws DocFileIOException if there is a problem writing the file
 415      */
 416     public void printHtmlDocument(List<String> metakeywords, boolean includeScript,
 417             Content body) throws DocFileIOException {
 418         DocType htmlDocType = DocType.forVersion(configuration.htmlVersion);
 419         Content htmlComment = contents.newPage;
 420         Head head = new Head(path, configuration.htmlVersion, configuration.docletVersion)
 421                 .setTimestamp(!configuration.notimestamp)
 422                 .setTitle(winTitle)


 932     /**
 933      * Return the path to the class page for a typeElement.
 934      *
 935      * @param te   TypeElement for which the path is requested.
 936      * @param name Name of the file(doesn't include path).
 937      */
 938     protected DocPath pathString(TypeElement te, DocPath name) {
 939         return pathString(utils.containingPackage(te), name);
 940     }
 941 
 942     /**
 943      * Return path to the given file name in the given package. So if the name
 944      * passed is "Object.html" and the name of the package is "java.lang", and
 945      * if the relative path is "../.." then returned string will be
 946      * "../../java/lang/Object.html"
 947      *
 948      * @param packageElement Package in which the file name is assumed to be.
 949      * @param name File name, to which path string is.
 950      */
 951     protected DocPath pathString(PackageElement packageElement, DocPath name) {
 952         return pathToRoot.resolve(DocPath.forPackage(packageElement).resolve(name));
 953     }
 954 
 955     /**
 956      * Given a package, return the name to be used in HTML anchor tag.
 957      * @param packageElement the package.
 958      * @return the name to be used in HTML anchor tag.
 959      */
 960     public String getPackageAnchorName(PackageElement packageElement) {
 961         return packageElement == null || packageElement.isUnnamed()
 962                 ? SectionName.UNNAMED_PACKAGE_ANCHOR.getName()
 963                 : utils.getPackageName(packageElement);
 964     }
 965 
 966     /**
 967      * Return the link to the given package.
 968      *
 969      * @param packageElement the package to link to.
 970      * @param label the label for the link.
 971      * @return a content tree for the package link.
 972      */


1004         } else {
1005             DocLink crossPkgLink = getCrossPackageLink(utils.getPackageName(packageElement));
1006             if (crossPkgLink != null) {
1007                 return links.createLink(crossPkgLink, label);
1008             } else {
1009                 return label;
1010             }
1011         }
1012     }
1013 
1014     /**
1015      * Get Module link.
1016      *
1017      * @param mdle the module being documented
1018      * @param label tag for the link
1019      * @return a content for the module link
1020      */
1021     public Content getModuleLink(ModuleElement mdle, Content label) {
1022         boolean included = utils.isIncluded(mdle);
1023         return (included)
1024                 ? links.createLink(pathToRoot.resolve(DocPaths.moduleSummary(mdle)), label, "", "")
1025                 : label;
1026     }
1027 
1028     public Content interfaceName(TypeElement typeElement, boolean qual) {
1029         Content name = new StringContent((qual)
1030                 ? typeElement.getQualifiedName()
1031                 : utils.getSimpleName(typeElement));
1032         return (utils.isInterface(typeElement)) ?  HtmlTree.SPAN(HtmlStyle.interfaceName, name) : name;
1033     }
1034 
1035     /**
1036      * Add the link to the content tree.
1037      *
1038      * @param typeElement program element typeElement for which the link will be added
1039      * @param label label for the link
1040      * @param htmltree the content tree to which the link will be added
1041      */
1042     public void addSrcLink(Element typeElement, Content label, Content htmltree) {
1043         if (typeElement == null) {
1044             return;
1045         }
1046         TypeElement te = utils.getEnclosingTypeElement(typeElement);
1047         if (te == null) {
1048             // must be a typeElement since in has no containing class.
1049             te = (TypeElement) typeElement;
1050         }
1051         DocPath href = pathToRoot
1052                 .resolve(DocPaths.SOURCE_OUTPUT)
1053                 .resolve(DocPath.forClass(utils, te));
1054         Content linkContent = links.createLink(href
1055                 .fragment(SourceToHTMLConverter.getAnchorName(utils, typeElement)), label, "", "");
1056         htmltree.addContent(linkContent);
1057     }
1058 
1059     /**
1060      * Return the link to the given class.
1061      *
1062      * @param linkInfo the information about the link.
1063      *
1064      * @return the link for the given class.
1065      */
1066     public Content getLink(LinkInfoImpl linkInfo) {
1067         LinkFactoryImpl factory = new LinkFactoryImpl(this);
1068         return factory.getLink(linkInfo);
1069     }
1070 
1071     /**
1072      * Return the type parameters for the given class.
1073      *


1122                     "", true);
1123             }
1124         }
1125         return null;
1126     }
1127 
1128     public boolean isClassLinkable(TypeElement typeElement) {
1129         if (utils.isIncluded(typeElement)) {
1130             return configuration.isGeneratedDoc(typeElement);
1131         }
1132         return configuration.extern.isExternal(typeElement);
1133     }
1134 
1135     public DocLink getCrossPackageLink(String pkgName) {
1136         return configuration.extern.getExternalLink(pkgName, pathToRoot,
1137             DocPaths.PACKAGE_SUMMARY.getPath());
1138     }
1139 
1140     public DocLink getCrossModuleLink(String mdleName) {
1141         return configuration.extern.getExternalLink(mdleName, pathToRoot,
1142             DocPaths.moduleSummary(mdleName).getPath());
1143     }
1144 
1145     /**
1146      * Get the class link.
1147      *
1148      * @param context the id of the context where the link will be added
1149      * @param element to link to
1150      * @return a content tree for the link
1151      */
1152     public Content getQualifiedClassLink(LinkInfoImpl.Kind context, Element element) {
1153         LinkInfoImpl linkInfoImpl = new LinkInfoImpl(configuration, context, (TypeElement)element);
1154         return getLink(linkInfoImpl.label(utils.getFullyQualifiedName(element)));
1155     }
1156 
1157     /**
1158      * Add the class link.
1159      *
1160      * @param context the id of the context where the link will be added
1161      * @param typeElement to link to
1162      * @param contentTree the content tree to which the link will be added


1981      * <p>
1982      * If this link appeared in the index, we would redirect
1983      * the link like this:
1984      *
1985      * {@literal <a href="./com/sun/javadoc/package-summary.html">The package Page</a>}
1986      *
1987      * @param element the Element object whose documentation is being written.
1988      * @param text the text being written.
1989      *
1990      * @return the text, with all the relative links redirected to work.
1991      */
1992     private String redirectRelativeLinks(Element element, TextTree tt) {
1993         String text = tt.getBody();
1994         if (element == null || utils.isOverviewElement(element) || shouldNotRedirectRelativeLinks()) {
1995             return text;
1996         }
1997 
1998         DocPath redirectPathFromRoot = new SimpleElementVisitor9<DocPath, Void>() {
1999             @Override
2000             public DocPath visitType(TypeElement e, Void p) {
2001                 return DocPath.forPackage(utils.containingPackage(e));
2002             }
2003 
2004             @Override
2005             public DocPath visitPackage(PackageElement e, Void p) {
2006                 return DocPath.forPackage(e);
2007             }
2008 
2009             @Override
2010             public DocPath visitVariable(VariableElement e, Void p) {
2011                 return DocPath.forPackage(utils.containingPackage(e));
2012             }
2013 
2014             @Override
2015             public DocPath visitExecutable(ExecutableElement e, Void p) {
2016                 return DocPath.forPackage(utils.containingPackage(e));
2017             }
2018 
2019             @Override
2020             protected DocPath defaultAction(Element e, Void p) {
2021                 return null;
2022             }
2023         }.visit(element);
2024         if (redirectPathFromRoot == null) {
2025             return text;
2026         }
2027         String lower = Utils.toLowerCase(text);
2028         if (!(lower.startsWith("mailto:")
2029                 || lower.startsWith("http:")
2030                 || lower.startsWith("https:")
2031                 || lower.startsWith("file:"))) {
2032             text = "{@" + (new DocRootTaglet()).getName() + "}/"
2033                     + redirectPathFromRoot.resolve(text).getPath();
2034             text = replaceDocRootDir(text);
2035         }
2036         return text;




 138      * Name of the file getting generated. If the file getting generated is
 139      * "java/lang/Object.html", then the filename is "Object.html".
 140      */
 141     public final DocPath filename;
 142 
 143     /**
 144      * The global configuration information for this run.
 145      */
 146     public final HtmlConfiguration configuration;
 147 
 148     protected final Utils utils;
 149 
 150     protected final Contents contents;
 151 
 152     protected final Messages messages;
 153 
 154     protected final Resources resources;
 155 
 156     protected final Links links;
 157 
 158     protected final DocPaths docPaths;
 159 
 160     /**
 161      * To check whether annotation heading is printed or not.
 162      */
 163     protected boolean printedAnnotationHeading = false;
 164 
 165     /**
 166      * To check whether annotation field heading is printed or not.
 167      */
 168     protected boolean printedAnnotationFieldHeading = false;
 169 
 170     /**
 171      * To check whether the repeated annotations is documented or not.
 172      */
 173     private boolean isAnnotationDocumented = false;
 174 
 175     /**
 176      * To check whether the container annotations is documented or not.
 177      */
 178     private boolean isContainerDocumented = false;
 179 


 187     protected String winTitle;
 188 
 189     protected Script mainBodyScript;
 190 
 191     /**
 192      * Constructor to construct the HtmlStandardWriter object.
 193      *
 194      * @param configuration the configuration for this doclet
 195      * @param path the file to be generated.
 196      */
 197     public HtmlDocletWriter(HtmlConfiguration configuration, DocPath path) {
 198         this.configuration = configuration;
 199         this.contents = configuration.contents;
 200         this.messages = configuration.messages;
 201         this.resources = configuration.resources;
 202         this.links = new Links(path, configuration.htmlVersion);
 203         this.utils = configuration.utils;
 204         this.path = path;
 205         this.pathToRoot = path.parent().invert();
 206         this.filename = path.basename();
 207         this.docPaths = configuration.docPaths;
 208 
 209         messages.notice("doclet.Generating_0",
 210             DocFile.createFileForOutput(configuration, path).getPath());
 211     }
 212 
 213     /**
 214      * Replace {@docRoot} tag used in options that accept HTML text, such
 215      * as -header, -footer, -top and -bottom, and when converting a relative
 216      * HREF where commentTagsToString inserts a {@docRoot} where one was
 217      * missing.  (Also see DocRootTaglet for {@docRoot} tags in doc
 218      * comments.)
 219      * <p>
 220      * Replace {@docRoot} tag in htmlstr with the relative path to the
 221      * destination directory from the directory where the file is being
 222      * written, looping to handle all such tags in htmlstr.
 223      * <p>
 224      * For example, for "-d docs" and -header containing {@docRoot}, when
 225      * the HTML page for source file p/C1.java is being generated, the
 226      * {@docRoot} tag would be inserted into the header as "../",
 227      * the relative path from docs/p/ to docs/ (the document root).


 385      * @param label tag for the link
 386      * @param mdle the module being documented
 387      * @return a content for the target module packages link
 388      */
 389     public Content getTargetModulePackageLink(PackageElement pkg, String target,
 390             Content label, ModuleElement mdle) {
 391         return links.createLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
 392                 label, "", target);
 393     }
 394 
 395     /**
 396      * Get Module link, with target frame.
 397      *
 398      * @param target name of the target frame
 399      * @param label tag for the link
 400      * @param mdle the module being documented
 401      * @return a content for the target module link
 402      */
 403     public Content getTargetModuleLink(String target, Content label, ModuleElement mdle) {
 404         return links.createLink(pathToRoot.resolve(
 405                 docPaths.moduleSummary(mdle)), label, "", target);
 406     }
 407 
 408     /**
 409      * Generates the HTML document tree and prints it out.
 410      *
 411      * @param metakeywords Array of String keywords for META tag. Each element
 412      *                     of the array is assigned to a separate META tag.
 413      *                     Pass in null for no array
 414      * @param includeScript true if printing windowtitle script
 415      *                      false for files that appear in the left-hand frames
 416      * @param body the body htmltree to be included in the document
 417      * @throws DocFileIOException if there is a problem writing the file
 418      */
 419     public void printHtmlDocument(List<String> metakeywords, boolean includeScript,
 420             Content body) throws DocFileIOException {
 421         DocType htmlDocType = DocType.forVersion(configuration.htmlVersion);
 422         Content htmlComment = contents.newPage;
 423         Head head = new Head(path, configuration.htmlVersion, configuration.docletVersion)
 424                 .setTimestamp(!configuration.notimestamp)
 425                 .setTitle(winTitle)


 935     /**
 936      * Return the path to the class page for a typeElement.
 937      *
 938      * @param te   TypeElement for which the path is requested.
 939      * @param name Name of the file(doesn't include path).
 940      */
 941     protected DocPath pathString(TypeElement te, DocPath name) {
 942         return pathString(utils.containingPackage(te), name);
 943     }
 944 
 945     /**
 946      * Return path to the given file name in the given package. So if the name
 947      * passed is "Object.html" and the name of the package is "java.lang", and
 948      * if the relative path is "../.." then returned string will be
 949      * "../../java/lang/Object.html"
 950      *
 951      * @param packageElement Package in which the file name is assumed to be.
 952      * @param name File name, to which path string is.
 953      */
 954     protected DocPath pathString(PackageElement packageElement, DocPath name) {
 955         return pathToRoot.resolve(docPaths.forPackage(packageElement).resolve(name));
 956     }
 957 
 958     /**
 959      * Given a package, return the name to be used in HTML anchor tag.
 960      * @param packageElement the package.
 961      * @return the name to be used in HTML anchor tag.
 962      */
 963     public String getPackageAnchorName(PackageElement packageElement) {
 964         return packageElement == null || packageElement.isUnnamed()
 965                 ? SectionName.UNNAMED_PACKAGE_ANCHOR.getName()
 966                 : utils.getPackageName(packageElement);
 967     }
 968 
 969     /**
 970      * Return the link to the given package.
 971      *
 972      * @param packageElement the package to link to.
 973      * @param label the label for the link.
 974      * @return a content tree for the package link.
 975      */


1007         } else {
1008             DocLink crossPkgLink = getCrossPackageLink(utils.getPackageName(packageElement));
1009             if (crossPkgLink != null) {
1010                 return links.createLink(crossPkgLink, label);
1011             } else {
1012                 return label;
1013             }
1014         }
1015     }
1016 
1017     /**
1018      * Get Module link.
1019      *
1020      * @param mdle the module being documented
1021      * @param label tag for the link
1022      * @return a content for the module link
1023      */
1024     public Content getModuleLink(ModuleElement mdle, Content label) {
1025         boolean included = utils.isIncluded(mdle);
1026         return (included)
1027                 ? links.createLink(pathToRoot.resolve(docPaths.moduleSummary(mdle)), label, "", "")
1028                 : label;
1029     }
1030 
1031     public Content interfaceName(TypeElement typeElement, boolean qual) {
1032         Content name = new StringContent((qual)
1033                 ? typeElement.getQualifiedName()
1034                 : utils.getSimpleName(typeElement));
1035         return (utils.isInterface(typeElement)) ?  HtmlTree.SPAN(HtmlStyle.interfaceName, name) : name;
1036     }
1037 
1038     /**
1039      * Add the link to the content tree.
1040      *
1041      * @param typeElement program element typeElement for which the link will be added
1042      * @param label label for the link
1043      * @param htmltree the content tree to which the link will be added
1044      */
1045     public void addSrcLink(Element typeElement, Content label, Content htmltree) {
1046         if (typeElement == null) {
1047             return;
1048         }
1049         TypeElement te = utils.getEnclosingTypeElement(typeElement);
1050         if (te == null) {
1051             // must be a typeElement since in has no containing class.
1052             te = (TypeElement) typeElement;
1053         }
1054         DocPath href = pathToRoot
1055                 .resolve(DocPaths.SOURCE_OUTPUT)
1056                 .resolve(docPaths.forClass(te));
1057         Content linkContent = links.createLink(href
1058                 .fragment(SourceToHTMLConverter.getAnchorName(utils, typeElement)), label, "", "");
1059         htmltree.addContent(linkContent);
1060     }
1061 
1062     /**
1063      * Return the link to the given class.
1064      *
1065      * @param linkInfo the information about the link.
1066      *
1067      * @return the link for the given class.
1068      */
1069     public Content getLink(LinkInfoImpl linkInfo) {
1070         LinkFactoryImpl factory = new LinkFactoryImpl(this);
1071         return factory.getLink(linkInfo);
1072     }
1073 
1074     /**
1075      * Return the type parameters for the given class.
1076      *


1125                     "", true);
1126             }
1127         }
1128         return null;
1129     }
1130 
1131     public boolean isClassLinkable(TypeElement typeElement) {
1132         if (utils.isIncluded(typeElement)) {
1133             return configuration.isGeneratedDoc(typeElement);
1134         }
1135         return configuration.extern.isExternal(typeElement);
1136     }
1137 
1138     public DocLink getCrossPackageLink(String pkgName) {
1139         return configuration.extern.getExternalLink(pkgName, pathToRoot,
1140             DocPaths.PACKAGE_SUMMARY.getPath());
1141     }
1142 
1143     public DocLink getCrossModuleLink(String mdleName) {
1144         return configuration.extern.getExternalLink(mdleName, pathToRoot,
1145             docPaths.moduleSummary(mdleName).getPath());
1146     }
1147 
1148     /**
1149      * Get the class link.
1150      *
1151      * @param context the id of the context where the link will be added
1152      * @param element to link to
1153      * @return a content tree for the link
1154      */
1155     public Content getQualifiedClassLink(LinkInfoImpl.Kind context, Element element) {
1156         LinkInfoImpl linkInfoImpl = new LinkInfoImpl(configuration, context, (TypeElement)element);
1157         return getLink(linkInfoImpl.label(utils.getFullyQualifiedName(element)));
1158     }
1159 
1160     /**
1161      * Add the class link.
1162      *
1163      * @param context the id of the context where the link will be added
1164      * @param typeElement to link to
1165      * @param contentTree the content tree to which the link will be added


1984      * <p>
1985      * If this link appeared in the index, we would redirect
1986      * the link like this:
1987      *
1988      * {@literal <a href="./com/sun/javadoc/package-summary.html">The package Page</a>}
1989      *
1990      * @param element the Element object whose documentation is being written.
1991      * @param text the text being written.
1992      *
1993      * @return the text, with all the relative links redirected to work.
1994      */
1995     private String redirectRelativeLinks(Element element, TextTree tt) {
1996         String text = tt.getBody();
1997         if (element == null || utils.isOverviewElement(element) || shouldNotRedirectRelativeLinks()) {
1998             return text;
1999         }
2000 
2001         DocPath redirectPathFromRoot = new SimpleElementVisitor9<DocPath, Void>() {
2002             @Override
2003             public DocPath visitType(TypeElement e, Void p) {
2004                 return docPaths.forPackage(utils.containingPackage(e));
2005             }
2006 
2007             @Override
2008             public DocPath visitPackage(PackageElement e, Void p) {
2009                 return docPaths.forPackage(e);
2010             }
2011 
2012             @Override
2013             public DocPath visitVariable(VariableElement e, Void p) {
2014                 return docPaths.forPackage(utils.containingPackage(e));
2015             }
2016 
2017             @Override
2018             public DocPath visitExecutable(ExecutableElement e, Void p) {
2019                 return docPaths.forPackage(utils.containingPackage(e));
2020             }
2021 
2022             @Override
2023             protected DocPath defaultAction(Element e, Void p) {
2024                 return null;
2025             }
2026         }.visit(element);
2027         if (redirectPathFromRoot == null) {
2028             return text;
2029         }
2030         String lower = Utils.toLowerCase(text);
2031         if (!(lower.startsWith("mailto:")
2032                 || lower.startsWith("http:")
2033                 || lower.startsWith("https:")
2034                 || lower.startsWith("file:"))) {
2035             text = "{@" + (new DocRootTaglet()).getName() + "}/"
2036                     + redirectPathFromRoot.resolve(text).getPath();
2037             text = replaceDocRootDir(text);
2038         }
2039         return text;


< prev index next >