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;
|