/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.javadoc.internal.doclets.formats.html;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleAnnotationValueVisitor9;
import javax.lang.model.util.SimpleElementVisitor9;
import javax.lang.model.util.SimpleTypeVisitor9;
import com.sun.source.doctree.AttributeTree;
import com.sun.source.doctree.AttributeTree.ValueKind;
import com.sun.source.doctree.CommentTree;
import com.sun.source.doctree.DocRootTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.EntityTree;
import com.sun.source.doctree.ErroneousTree;
import com.sun.source.doctree.IndexTree;
import com.sun.source.doctree.InheritDocTree;
import com.sun.source.doctree.LinkTree;
import com.sun.source.doctree.LiteralTree;
import com.sun.source.doctree.SeeTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.util.SimpleDocTreeVisitor;
import jdk.javadoc.internal.doclets.formats.html.markup.Comment;
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocWriter;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
import jdk.javadoc.internal.doclets.toolkit.Configuration;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.taglets.DocRootTaglet;
import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter;
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
import jdk.javadoc.internal.doclets.toolkit.util.ImplementedMethods;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
import static com.sun.source.doctree.AttributeTree.ValueKind.*;
import static com.sun.source.doctree.DocTree.Kind.*;
import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocWriter.CONTENT_TYPE;
import static jdk.javadoc.internal.doclets.toolkit.util.CommentHelper.SPACER;
Class for the Html Format Code Generation specific to JavaDoc.
This Class contains methods related to the Html Code Generation which
are used extensively while generating the entire documentation.
This is NOT part of any supported API.
If you write code that depends on this, you do so at your own risk.
This code and its internal interfaces are subject to change or
deletion without notice.
Author: Atul M Dambalkar, Robert Field, Bhavesh Patel (Modified)
/**
* Class for the Html Format Code Generation specific to JavaDoc.
* This Class contains methods related to the Html Code Generation which
* are used extensively while generating the entire documentation.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @author Atul M Dambalkar
* @author Robert Field
* @author Bhavesh Patel (Modified)
*/
public class HtmlDocletWriter extends HtmlDocWriter {
Relative path from the file getting generated to the destination
directory. For example, if the file getting generated is
"java/lang/Object.html", then the path to the root is "../..".
This string can be empty if the file getting generated is in
the destination directory.
/**
* Relative path from the file getting generated to the destination
* directory. For example, if the file getting generated is
* "java/lang/Object.html", then the path to the root is "../..".
* This string can be empty if the file getting generated is in
* the destination directory.
*/
public final DocPath pathToRoot;
Platform-independent path from the current or the
destination directory to the file getting generated.
Used when creating the file.
/**
* Platform-independent path from the current or the
* destination directory to the file getting generated.
* Used when creating the file.
*/
public final DocPath path;
Name of the file getting generated. If the file getting generated is
"java/lang/Object.html", then the filename is "Object.html".
/**
* Name of the file getting generated. If the file getting generated is
* "java/lang/Object.html", then the filename is "Object.html".
*/
public final DocPath filename;
The global configuration information for this run.
/**
* The global configuration information for this run.
*/
public final ConfigurationImpl configuration;
protected final Utils utils;
protected final Contents contents;
protected final Messages messages;
protected final Resources resources;
To check whether annotation heading is printed or not.
/**
* To check whether annotation heading is printed or not.
*/
protected boolean printedAnnotationHeading = false;
To check whether annotation field heading is printed or not.
/**
* To check whether annotation field heading is printed or not.
*/
protected boolean printedAnnotationFieldHeading = false;
To check whether the repeated annotations is documented or not.
/**
* To check whether the repeated annotations is documented or not.
*/
private boolean isAnnotationDocumented = false;
To check whether the container annotations is documented or not.
/**
* To check whether the container annotations is documented or not.
*/
private boolean isContainerDocumented = false;
HtmlTree fixedNavDiv = new HtmlTree(HtmlTag.DIV);
final static Pattern IMPROPER_HTML_CHARS = Pattern.compile(".*[&<>].*");
Constructor to construct the HtmlStandardWriter object.
Params: - path – File to be generated.
/**
* Constructor to construct the HtmlStandardWriter object.
*
* @param path File to be generated.
*/
public HtmlDocletWriter(ConfigurationImpl configuration, DocPath path) {
super(configuration, path);
this.configuration = configuration;
this.contents = configuration.contents;
this.messages = configuration.messages;
this.resources = configuration.resources;
this.utils = configuration.utils;
this.path = path;
this.pathToRoot = path.parent().invert();
this.filename = path.basename();
}
Replace {@docRoot} tag used in options that accept HTML text, such
as -header, -footer, -top and -bottom, and when converting a relative
HREF where commentTagsToString inserts a {@docRoot} where one was
missing. (Also see DocRootTaglet for {@docRoot} tags in doc
comments.)
Replace {@docRoot} tag in htmlstr with the relative path to the
destination directory from the directory where the file is being
written, looping to handle all such tags in htmlstr.
For example, for "-d docs" and -header containing {@docRoot}, when
the HTML page for source file p/C1.java is being generated, the
{@docRoot} tag would be inserted into the header as "../",
the relative path from docs/p/ to docs/ (the document root).
Note: This doc comment was written with '@' representing '@'
to prevent the inline tag from being interpreted.
/**
* Replace {@docRoot} tag used in options that accept HTML text, such
* as -header, -footer, -top and -bottom, and when converting a relative
* HREF where commentTagsToString inserts a {@docRoot} where one was
* missing. (Also see DocRootTaglet for {@docRoot} tags in doc
* comments.)
* <p>
* Replace {@docRoot} tag in htmlstr with the relative path to the
* destination directory from the directory where the file is being
* written, looping to handle all such tags in htmlstr.
* <p>
* For example, for "-d docs" and -header containing {@docRoot}, when
* the HTML page for source file p/C1.java is being generated, the
* {@docRoot} tag would be inserted into the header as "../",
* the relative path from docs/p/ to docs/ (the document root).
* <p>
* Note: This doc comment was written with '&#064;' representing '@'
* to prevent the inline tag from being interpreted.
*/
public String replaceDocRootDir(String htmlstr) {
// Return if no inline tags exist
int index = htmlstr.indexOf("{@");
if (index < 0) {
return htmlstr;
}
Matcher docrootMatcher = docrootPattern.matcher(htmlstr);
if (!docrootMatcher.find()) {
return htmlstr;
}
StringBuilder buf = new StringBuilder();
int prevEnd = 0;
do {
int match = docrootMatcher.start();
// append htmlstr up to start of next {@docroot}
buf.append(htmlstr.substring(prevEnd, match));
prevEnd = docrootMatcher.end();
if (configuration.docrootparent.length() > 0 && htmlstr.startsWith("/..", prevEnd)) {
// Insert the absolute link if {@docRoot} is followed by "/..".
buf.append(configuration.docrootparent);
prevEnd += 3;
} else {
// Insert relative path where {@docRoot} was located
buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath());
}
// Append slash if next character is not a slash
if (prevEnd < htmlstr.length() && htmlstr.charAt(prevEnd) != '/') {
buf.append('/');
}
} while (docrootMatcher.find());
buf.append(htmlstr.substring(prevEnd));
return buf.toString();
}
//where:
// Note: {@docRoot} is not case sensitive when passed in w/command line option:
private static final Pattern docrootPattern =
Pattern.compile(Pattern.quote("{@docroot}"), Pattern.CASE_INSENSITIVE);
Get the script to show or hide the All classes link.
Params: - id – id of the element to show or hide
Returns: a content tree for the script
/**
* Get the script to show or hide the All classes link.
*
* @param id id of the element to show or hide
* @return a content tree for the script
*/
public Content getAllClassesLinkScript(String id) {
HtmlTree script = HtmlTree.SCRIPT();
String scriptCode = "<!--\n" +
" allClassesLink = document.getElementById(\"" + id + "\");\n" +
" if(window==top) {\n" +
" allClassesLink.style.display = \"block\";\n" +
" }\n" +
" else {\n" +
" allClassesLink.style.display = \"none\";\n" +
" }\n" +
" //-->\n";
Content scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
script.addContent(scriptContent);
Content div = HtmlTree.DIV(script);
Content div_noscript = HtmlTree.DIV(contents.noScriptMessage);
Content noScript = HtmlTree.NOSCRIPT(div_noscript);
div.addContent(noScript);
return div;
}
Add method information.
Params: - method – the method to be documented
- dl – the content tree to which the method information will be added
/**
* Add method information.
*
* @param method the method to be documented
* @param dl the content tree to which the method information will be added
*/
private void addMethodInfo(ExecutableElement method, Content dl) {
TypeElement enclosing = utils.getEnclosingTypeElement(method);
List<? extends TypeMirror> intfacs = enclosing.getInterfaces();
ExecutableElement overriddenMethod = utils.overriddenMethod(method);
// Check whether there is any implementation or overridden info to be
// printed. If no overridden or implementation info needs to be
// printed, do not print this section.
if ((!intfacs.isEmpty()
&& new ImplementedMethods(method, this.configuration).build().isEmpty() == false)
|| overriddenMethod != null) {
MethodWriterImpl.addImplementsInfo(this, method, dl);
if (overriddenMethod != null) {
MethodWriterImpl.addOverridden(this,
utils.overriddenType(method),
overriddenMethod,
dl);
}
}
}
Adds the tags information.
Params: - e – the Element for which the tags will be generated
- htmltree – the documentation tree to which the tags will be added
/**
* Adds the tags information.
*
* @param e the Element for which the tags will be generated
* @param htmltree the documentation tree to which the tags will be added
*/
protected void addTagsInfo(Element e, Content htmltree) {
if (configuration.nocomment) {
return;
}
Content dl = new HtmlTree(HtmlTag.DL);
if (utils.isExecutableElement(e) && !utils.isConstructor(e)) {
addMethodInfo((ExecutableElement)e, dl);
}
Content output = new ContentBuilder();
TagletWriter.genTagOutput(configuration.tagletManager, e,
configuration.tagletManager.getCustomTaglets(e),
getTagletWriterInstance(false), output);
dl.addContent(output);
htmltree.addContent(dl);
}
Check whether there are any tags for Serialization Overview
section to be printed.
Params: - field – the VariableElement object to check for tags.
Returns: true if there are tags to be printed else return false.
/**
* Check whether there are any tags for Serialization Overview
* section to be printed.
*
* @param field the VariableElement object to check for tags.
* @return true if there are tags to be printed else return false.
*/
protected boolean hasSerializationOverviewTags(VariableElement field) {
Content output = new ContentBuilder();
TagletWriter.genTagOutput(configuration.tagletManager, field,
configuration.tagletManager.getCustomTaglets(field),
getTagletWriterInstance(false), output);
return !output.isEmpty();
}
Returns a TagletWriter that knows how to write HTML.
Returns: a TagletWriter that knows how to write HTML.
/**
* Returns a TagletWriter that knows how to write HTML.
*
* @return a TagletWriter that knows how to write HTML.
*/
public TagletWriter getTagletWriterInstance(boolean isFirstSentence) {
return new TagletWriterImpl(this, isFirstSentence);
}
Get Package link, with target frame.
Params: - pkg – The link will be to the "package-summary.html" page for this package
- target – name of the target frame
- label – tag for the link
Returns: a content for the target package link
/**
* Get Package link, with target frame.
*
* @param pkg The link will be to the "package-summary.html" page for this package
* @param target name of the target frame
* @param label tag for the link
* @return a content for the target package link
*/
public Content getTargetPackageLink(PackageElement pkg, String target,
Content label) {
return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY), label, "", target);
}
Get Module Package link, with target frame.
Params: - pkg – the PackageElement
- target – name of the target frame
- label – tag for the link
- mdle – the module being documented
Returns: a content for the target module packages link
/**
* Get Module Package link, with target frame.
*
* @param pkg the PackageElement
* @param target name of the target frame
* @param label tag for the link
* @param mdle the module being documented
* @return a content for the target module packages link
*/
public Content getTargetModulePackageLink(PackageElement pkg, String target,
Content label, ModuleElement mdle) {
return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY),
label, "", target);
}
Get Module link, with target frame.
Params: - target – name of the target frame
- label – tag for the link
- mdle – the module being documented
Returns: a content for the target module link
/**
* Get Module link, with target frame.
*
* @param target name of the target frame
* @param label tag for the link
* @param mdle the module being documented
* @return a content for the target module link
*/
public Content getTargetModuleLink(String target, Content label, ModuleElement mdle) {
return getHyperLink(pathToRoot.resolve(
DocPaths.moduleSummary(mdle)), label, "", target);
}
public void addClassesSummary(SortedSet<TypeElement> classes, String label,
String tableSummary, List<String> tableHeader, Content summaryContentTree) {
if (!classes.isEmpty()) {
Content caption = getTableCaption(new RawHtml(label));
Content table = (configuration.isOutputHtml5())
? HtmlTree.TABLE(HtmlStyle.typeSummary, caption)
: HtmlTree.TABLE(HtmlStyle.typeSummary, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
for (TypeElement te : classes) {
if (!utils.isCoreClass(te) ||
!configuration.isGeneratedDoc(te)) {
continue;
}
Content classContent = getLink(new LinkInfoImpl(
configuration, LinkInfoImpl.Kind.PACKAGE, te));
Content tdClass = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, classContent);
HtmlTree tr = HtmlTree.TR(tdClass);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
altColor = !altColor;
HtmlTree tdClassDescription = new HtmlTree(HtmlTag.TD);
tdClassDescription.addStyle(HtmlStyle.colLast);
if (utils.isDeprecated(te)) {
tdClassDescription.addContent(getDeprecatedPhrase(te));
List<? extends DocTree> tags = utils.getDeprecatedTrees(te);
if (!tags.isEmpty()) {
addSummaryDeprecatedComment(te, tags.get(0), tdClassDescription);
}
} else {
addSummaryComment(te, tdClassDescription);
}
tr.addContent(tdClassDescription);
tbody.addContent(tr);
}
table.addContent(tbody);
summaryContentTree.addContent(table);
}
}
Generates the HTML document tree and prints it out.
Params: - metakeywords – Array of String keywords for META tag. Each element
of the array is assigned to a separate META tag.
Pass in null for no array
- includeScript – true if printing windowtitle script
false for files that appear in the left-hand frames
- body – the body htmltree to be included in the document
Throws: - DocFileIOException – if there is a problem writing the file
/**
* Generates the HTML document tree and prints it out.
*
* @param metakeywords Array of String keywords for META tag. Each element
* of the array is assigned to a separate META tag.
* Pass in null for no array
* @param includeScript true if printing windowtitle script
* false for files that appear in the left-hand frames
* @param body the body htmltree to be included in the document
* @throws DocFileIOException if there is a problem writing the file
*/
public void printHtmlDocument(List<String> metakeywords, boolean includeScript,
Content body) throws DocFileIOException {
Content htmlDocType = configuration.isOutputHtml5()
? DocType.HTML5
: DocType.TRANSITIONAL;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
head.addContent(getGeneratedBy(!configuration.notimestamp));
head.addContent(getTitle());
Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
(configuration.charset.length() > 0) ?
configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
head.addContent(meta);
if (!configuration.notimestamp) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
meta = HtmlTree.META(configuration.isOutputHtml5()
? "dc.created"
: "date", dateFormat.format(new Date()));
head.addContent(meta);
}
if (metakeywords != null) {
for (String metakeyword : metakeywords) {
meta = HtmlTree.META("keywords", metakeyword);
head.addContent(meta);
}
}
addStyleSheetProperties(head);
addScriptProperties(head);
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body);
Content htmlDocument = new HtmlDocument(htmlDocType,
htmlComment, htmlTree);
write(htmlDocument);
}
Get the window title.
Params: - title – the title string to construct the complete window title
Returns: the window title string
/**
* Get the window title.
*
* @param title the title string to construct the complete window title
* @return the window title string
*/
public String getWindowTitle(String title) {
if (configuration.windowtitle.length() > 0) {
title += " (" + configuration.windowtitle + ")";
}
return title;
}
Get user specified header and the footer.
Params: - header – if true print the user provided header else print the
user provided footer.
/**
* Get user specified header and the footer.
*
* @param header if true print the user provided header else print the
* user provided footer.
*/
public Content getUserHeaderFooter(boolean header) {
String content;
if (header) {
content = replaceDocRootDir(configuration.header);
} else {
if (configuration.footer.length() != 0) {
content = replaceDocRootDir(configuration.footer);
} else {
content = replaceDocRootDir(configuration.header);
}
}
Content rawContent = new RawHtml(content);
return rawContent;
}
Adds the user specified top.
Params: - htmlTree – the content tree to which user specified top will be added
/**
* Adds the user specified top.
*
* @param htmlTree the content tree to which user specified top will be added
*/
public void addTop(Content htmlTree) {
Content top = new RawHtml(replaceDocRootDir(configuration.top));
fixedNavDiv.addContent(top);
}
Adds the user specified bottom.
Params: - htmlTree – the content tree to which user specified bottom will be added
/**
* Adds the user specified bottom.
*
* @param htmlTree the content tree to which user specified bottom will be added
*/
public void addBottom(Content htmlTree) {
Content bottom = new RawHtml(replaceDocRootDir(configuration.bottom));
Content small = HtmlTree.SMALL(bottom);
Content p = HtmlTree.P(HtmlStyle.legalCopy, small);
htmlTree.addContent(p);
}
Adds the navigation bar for the Html page at the top and and the bottom.
Params: - header – If true print navigation bar at the top of the page else
- htmlTree – the HtmlTree to which the nav links will be added
/**
* Adds the navigation bar for the Html page at the top and and the bottom.
*
* @param header If true print navigation bar at the top of the page else
* @param htmlTree the HtmlTree to which the nav links will be added
*/
protected void addNavLinks(boolean header, Content htmlTree) {
if (!configuration.nonavbar) {
Content tree = (configuration.allowTag(HtmlTag.NAV))
? HtmlTree.NAV()
: htmlTree;
String allClassesId = "allclasses_";
HtmlTree navDiv = new HtmlTree(HtmlTag.DIV);
fixedNavDiv.addStyle(HtmlStyle.fixedNav);
Content skipNavLinks = configuration.getContent("doclet.Skip_navigation_links");
if (header) {
fixedNavDiv.addContent(HtmlConstants.START_OF_TOP_NAVBAR);
navDiv.addStyle(HtmlStyle.topNav);
allClassesId += "navbar_top";
Content a = getMarkerAnchor(SectionName.NAVBAR_TOP);
//WCAG - Hyperlinks should contain text or an image with alt text - for AT tools
navDiv.addContent(a);
Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
getDocLink(SectionName.SKIP_NAVBAR_TOP), skipNavLinks,
skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
} else {
tree.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
navDiv.addStyle(HtmlStyle.bottomNav);
allClassesId += "navbar_bottom";
Content a = getMarkerAnchor(SectionName.NAVBAR_BOTTOM);
navDiv.addContent(a);
Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav, getHyperLink(
getDocLink(SectionName.SKIP_NAVBAR_BOTTOM), skipNavLinks,
skipNavLinks.toString(), ""));
navDiv.addContent(skipLinkContent);
}
if (header) {
navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_TOP_FIRSTROW));
} else {
navDiv.addContent(getMarkerAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW));
}
HtmlTree navList = new HtmlTree(HtmlTag.UL);
navList.addStyle(HtmlStyle.navList);
navList.addAttr(HtmlAttr.TITLE,
configuration.getText("doclet.Navigation"));
if (configuration.createoverview) {
navList.addContent(getNavLinkContents());
}
if (configuration.showModules) {
if (configuration.modules.size() == 1) {
navList.addContent(getNavLinkModule(configuration.modules.first()));
} else if (!configuration.modules.isEmpty()) {
navList.addContent(getNavLinkModule());
}
}
if (configuration.packages.size() == 1) {
navList.addContent(getNavLinkPackage(configuration.packages.first()));
} else if (!configuration.packages.isEmpty()) {
navList.addContent(getNavLinkPackage());
}
navList.addContent(getNavLinkClass());
if(configuration.classuse) {
navList.addContent(getNavLinkClassUse());
}
if(configuration.createtree) {
navList.addContent(getNavLinkTree());
}
if(!(configuration.nodeprecated ||
configuration.nodeprecatedlist)) {
navList.addContent(getNavLinkDeprecated());
}
if(configuration.createindex) {
navList.addContent(getNavLinkIndex());
}
if (!configuration.nohelp) {
navList.addContent(getNavLinkHelp());
}
navDiv.addContent(navList);
Content aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, getUserHeaderFooter(header));
navDiv.addContent(aboutDiv);
if (header) {
fixedNavDiv.addContent(navDiv);
} else {
tree.addContent(navDiv);
}
Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious(), getNavLinkNext());
Content subDiv = HtmlTree.DIV(HtmlStyle.subNav, ulNav);
if (configuration.frames) {
Content ulFrames = HtmlTree.UL(HtmlStyle.navList,
getNavShowLists(), getNavHideLists(filename));
subDiv.addContent(ulFrames);
}
HtmlTree ulAllClasses = HtmlTree.UL(HtmlStyle.navList, getNavLinkClassIndex());
ulAllClasses.addAttr(HtmlAttr.ID, allClassesId);
subDiv.addContent(ulAllClasses);
if (header && configuration.createindex) {
HtmlTree inputText = HtmlTree.INPUT("text", "search");
HtmlTree inputReset = HtmlTree.INPUT("reset", "reset");
Content searchTxt = new ContentBuilder();
searchTxt.addContent(configuration.getContent("doclet.search"));
searchTxt.addContent(Contents.SPACE);
HtmlTree liInput = HtmlTree.LI(HtmlTree.SPAN(searchTxt));
liInput.addContent(inputText);
liInput.addContent(inputReset);
HtmlTree ulSearch = HtmlTree.UL(HtmlStyle.navListSearch, liInput);
subDiv.addContent(ulSearch);
}
subDiv.addContent(getAllClassesLinkScript(allClassesId));
addSummaryDetailLinks(subDiv);
if (header) {
subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_TOP));
fixedNavDiv.addContent(subDiv);
fixedNavDiv.addContent(HtmlConstants.END_OF_TOP_NAVBAR);
tree.addContent(fixedNavDiv);
HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
tree.addContent(paddingDiv);
HtmlTree scriptTree = HtmlTree.SCRIPT();
String scriptCode = "<!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n";
RawHtml scriptContent = new RawHtml(scriptCode.replace("\n", DocletConstants.NL));
scriptTree.addContent(scriptContent);
tree.addContent(scriptTree);
} else {
subDiv.addContent(getMarkerAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
tree.addContent(subDiv);
tree.addContent(HtmlConstants.END_OF_BOTTOM_NAVBAR);
}
if (configuration.allowTag(HtmlTag.NAV)) {
htmlTree.addContent(tree);
}
}
}
Get the word "NEXT" to indicate that no link is available. Override
this method to customize next link.
Returns: a content tree for the link
/**
* Get the word "NEXT" to indicate that no link is available. Override
* this method to customize next link.
*
* @return a content tree for the link
*/
protected Content getNavLinkNext() {
return getNavLinkNext(null);
}
Get the word "PREV" to indicate that no link is available. Override
this method to customize prev link.
Returns: a content tree for the link
/**
* Get the word "PREV" to indicate that no link is available. Override
* this method to customize prev link.
*
* @return a content tree for the link
*/
protected Content getNavLinkPrevious() {
return getNavLinkPrevious(null);
}
Do nothing. This is the default method.
/**
* Do nothing. This is the default method.
*/
protected void addSummaryDetailLinks(Content navDiv) {
}
Get link to the "overview-summary.html" page.
Returns: a content tree for the link
/**
* Get link to the "overview-summary.html" page.
*
* @return a content tree for the link
*/
protected Content getNavLinkContents() {
Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
contents.overviewLabel, "", "");
Content li = HtmlTree.LI(linkContent);
return li;
}
Get link to the module summary page for the module passed.
Params: - mdle – Module to which link will be generated
Returns: a content tree for the link
/**
* Get link to the module summary page for the module passed.
*
* @param mdle Module to which link will be generated
* @return a content tree for the link
*/
protected Content getNavLinkModule(ModuleElement mdle) {
Content linkContent = getModuleLink(mdle, contents.moduleLabel);
Content li = HtmlTree.LI(linkContent);
return li;
}
Get the word "Module", to indicate that link is not available here.
Returns: a content tree for the link
/**
* Get the word "Module", to indicate that link is not available here.
*
* @return a content tree for the link
*/
protected Content getNavLinkModule() {
Content li = HtmlTree.LI(contents.moduleLabel);
return li;
}
Get link to the "package-summary.html" page for the package passed.
Params: - pkg – Package to which link will be generated
Returns: a content tree for the link
/**
* Get link to the "package-summary.html" page for the package passed.
*
* @param pkg Package to which link will be generated
* @return a content tree for the link
*/
protected Content getNavLinkPackage(PackageElement pkg) {
Content linkContent = getPackageLink(pkg, contents.packageLabel);
Content li = HtmlTree.LI(linkContent);
return li;
}
Get the word "Package" , to indicate that link is not available here.
Returns: a content tree for the link
/**
* Get the word "Package" , to indicate that link is not available here.
*
* @return a content tree for the link
*/
protected Content getNavLinkPackage() {
Content li = HtmlTree.LI(contents.packageLabel);
return li;
}
Get the word "Use", to indicate that link is not available.
Returns: a content tree for the link
/**
* Get the word "Use", to indicate that link is not available.
*
* @return a content tree for the link
*/
protected Content getNavLinkClassUse() {
Content li = HtmlTree.LI(contents.useLabel);
return li;
}
Get link for previous file.
Params: - prev – File name for the prev link
Returns: a content tree for the link
/**
* Get link for previous file.
*
* @param prev File name for the prev link
* @return a content tree for the link
*/
public Content getNavLinkPrevious(DocPath prev) {
Content li;
if (prev != null) {
li = HtmlTree.LI(getHyperLink(prev, contents.prevLabel, "", ""));
}
else
li = HtmlTree.LI(contents.prevLabel);
return li;
}
Get link for next file. If next is null, just print the label
without linking it anywhere.
Params: - next – File name for the next link
Returns: a content tree for the link
/**
* Get link for next file. If next is null, just print the label
* without linking it anywhere.
*
* @param next File name for the next link
* @return a content tree for the link
*/
public Content getNavLinkNext(DocPath next) {
Content li;
if (next != null) {
li = HtmlTree.LI(getHyperLink(next, contents.nextLabel, "", ""));
}
else
li = HtmlTree.LI(contents.nextLabel);
return li;
}
Get "FRAMES" link, to switch to the frame version of the output.
Params: - link – File to be linked, "index.html"
Returns: a content tree for the link
/**
* Get "FRAMES" link, to switch to the frame version of the output.
*
* @param link File to be linked, "index.html"
* @return a content tree for the link
*/
protected Content getNavShowLists(DocPath link) {
DocLink dl = new DocLink(link, path.getPath(), null);
Content framesContent = getHyperLink(dl, contents.framesLabel, "", "_top");
Content li = HtmlTree.LI(framesContent);
return li;
}
Get "FRAMES" link, to switch to the frame version of the output.
Returns: a content tree for the link
/**
* Get "FRAMES" link, to switch to the frame version of the output.
*
* @return a content tree for the link
*/
protected Content getNavShowLists() {
return getNavShowLists(pathToRoot.resolve(DocPaths.INDEX));
}
Get "NO FRAMES" link, to switch to the non-frame version of the output.
Params: - link – File to be linked
Returns: a content tree for the link
/**
* Get "NO FRAMES" link, to switch to the non-frame version of the output.
*
* @param link File to be linked
* @return a content tree for the link
*/
protected Content getNavHideLists(DocPath link) {
Content noFramesContent = getHyperLink(link, contents.noFramesLabel, "", "_top");
Content li = HtmlTree.LI(noFramesContent);
return li;
}
Get "Tree" link in the navigation bar. If there is only one package
specified on the command line, then the "Tree" link will be to the
only "package-tree.html" file otherwise it will be to the
"overview-tree.html" file.
Returns: a content tree for the link
/**
* Get "Tree" link in the navigation bar. If there is only one package
* specified on the command line, then the "Tree" link will be to the
* only "package-tree.html" file otherwise it will be to the
* "overview-tree.html" file.
*
* @return a content tree for the link
*/
protected Content getNavLinkTree() {
List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackageElements());
DocPath docPath = packages.size() == 1 && configuration.getSpecifiedTypeElements().isEmpty()
? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));
}
Get the overview tree link for the main tree.
Params: - label – the label for the link
Returns: a content tree for the link
/**
* Get the overview tree link for the main tree.
*
* @param label the label for the link
* @return a content tree for the link
*/
protected Content getNavLinkMainTree(String label) {
Content mainTreeContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE),
new StringContent(label));
Content li = HtmlTree.LI(mainTreeContent);
return li;
}
Get the word "Class", to indicate that class link is not available.
Returns: a content tree for the link
/**
* Get the word "Class", to indicate that class link is not available.
*
* @return a content tree for the link
*/
protected Content getNavLinkClass() {
Content li = HtmlTree.LI(contents.classLabel);
return li;
}
Get "Deprecated" API link in the navigation bar.
Returns: a content tree for the link
/**
* Get "Deprecated" API link in the navigation bar.
*
* @return a content tree for the link
*/
protected Content getNavLinkDeprecated() {
Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
contents.deprecatedLabel, "", "");
Content li = HtmlTree.LI(linkContent);
return li;
}
Get link for generated index. If the user has used "-splitindex"
command line option, then link to file "index-files/index-1.html" is
generated otherwise link to file "index-all.html" is generated.
Returns: a content tree for the link
/**
* Get link for generated index. If the user has used "-splitindex"
* command line option, then link to file "index-files/index-1.html" is
* generated otherwise link to file "index-all.html" is generated.
*
* @return a content tree for the link
*/
protected Content getNavLinkClassIndex() {
Content allClassesContent = getHyperLink(pathToRoot.resolve(
DocPaths.AllClasses(configuration.frames)),
contents.allClassesLabel, "", "");
Content li = HtmlTree.LI(allClassesContent);
return li;
}
Get link for generated class index.
Returns: a content tree for the link
/**
* Get link for generated class index.
*
* @return a content tree for the link
*/
protected Content getNavLinkIndex() {
Content linkContent = getHyperLink(pathToRoot.resolve(
(configuration.splitindex
? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
: DocPaths.INDEX_ALL)),
contents.indexLabel, "", "");
Content li = HtmlTree.LI(linkContent);
return li;
}
Get help file link. If user has provided a help file, then generate a
link to the user given file, which is already copied to current or
destination directory.
Returns: a content tree for the link
/**
* Get help file link. If user has provided a help file, then generate a
* link to the user given file, which is already copied to current or
* destination directory.
*
* @return a content tree for the link
*/
protected Content getNavLinkHelp() {
String helpfile = configuration.helpfile;
DocPath helpfilenm;
if (helpfile.isEmpty()) {
helpfilenm = DocPaths.HELP_DOC;
} else {
DocFile file = DocFile.createFileForInput(configuration, helpfile);
helpfilenm = DocPath.create(file.getName());
}
Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm),
contents.helpLabel, "", "");
Content li = HtmlTree.LI(linkContent);
return li;
}
Add gap between navigation bar elements.
Params: - liNav – the content tree to which the gap will be added
/**
* Add gap between navigation bar elements.
*
* @param liNav the content tree to which the gap will be added
*/
protected void addNavGap(Content liNav) {
liNav.addContent(Contents.SPACE);
liNav.addContent("|");
liNav.addContent(Contents.SPACE);
}
Get summary table header.
Params: - header – the header for the table
- scope – the scope of the headers
Returns: a content tree for the header
/**
* Get summary table header.
*
* @param header the header for the table
* @param scope the scope of the headers
* @return a content tree for the header
*/
public Content getSummaryTableHeader(List<String> header, String scope) {
Content tr = new HtmlTree(HtmlTag.TR);
final int size = header.size();
Content tableHeader;
if (size == 2) {
tableHeader = new StringContent(header.get(0));
tr.addContent(HtmlTree.TH(HtmlStyle.colFirst, scope, tableHeader));
tableHeader = new StringContent(header.get(1));
tr.addContent(HtmlTree.TH(HtmlStyle.colLast, scope, tableHeader));
return tr;
}
for (int i = 0; i < size; i++) {
tableHeader = new StringContent(header.get(i));
if (i == 0)
tr.addContent(HtmlTree.TH(HtmlStyle.colFirst, scope, tableHeader));
else if (i == 1)
tr.addContent(HtmlTree.TH(HtmlStyle.colSecond, scope, tableHeader));
else if (i == (size - 1))
tr.addContent(HtmlTree.TH(HtmlStyle.colLast, scope, tableHeader));
else
tr.addContent(HtmlTree.TH(scope, tableHeader));
}
return tr;
}
Get table caption.
Params: - rawText – the caption for the table which could be raw Html
Returns: a content tree for the caption
/**
* Get table caption.
*
* @param rawText the caption for the table which could be raw Html
* @return a content tree for the caption
*/
public Content getTableCaption(Content title) {
Content captionSpan = HtmlTree.SPAN(title);
Content space = Contents.SPACE;
Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, space);
Content caption = HtmlTree.CAPTION(captionSpan);
caption.addContent(tabSpan);
return caption;
}
Get the marker anchor which will be added to the documentation tree.
Params: - anchorName – the anchor name attribute
Returns: a content tree for the marker anchor
/**
* Get the marker anchor which will be added to the documentation tree.
*
* @param anchorName the anchor name attribute
* @return a content tree for the marker anchor
*/
public Content getMarkerAnchor(String anchorName) {
return getMarkerAnchor(getName(anchorName), null);
}
Get the marker anchor which will be added to the documentation tree.
Params: - sectionName – the section name anchor attribute for page
Returns: a content tree for the marker anchor
/**
* Get the marker anchor which will be added to the documentation tree.
*
* @param sectionName the section name anchor attribute for page
* @return a content tree for the marker anchor
*/
public Content getMarkerAnchor(SectionName sectionName) {
return getMarkerAnchor(sectionName.getName(), null);
}
Get the marker anchor which will be added to the documentation tree.
Params: - sectionName – the section name anchor attribute for page
- anchorName – the anchor name combined with section name attribute for the page
Returns: a content tree for the marker anchor
/**
* Get the marker anchor which will be added to the documentation tree.
*
* @param sectionName the section name anchor attribute for page
* @param anchorName the anchor name combined with section name attribute for the page
* @return a content tree for the marker anchor
*/
public Content getMarkerAnchor(SectionName sectionName, String anchorName) {
return getMarkerAnchor(sectionName.getName() + getName(anchorName), null);
}
Get the marker anchor which will be added to the documentation tree.
Params: - anchorName – the anchor name or id attribute
- anchorContent – the content that should be added to the anchor
Returns: a content tree for the marker anchor
/**
* Get the marker anchor which will be added to the documentation tree.
*
* @param anchorName the anchor name or id attribute
* @param anchorContent the content that should be added to the anchor
* @return a content tree for the marker anchor
*/
public Content getMarkerAnchor(String anchorName, Content anchorContent) {
if (anchorContent == null)
anchorContent = new Comment(" ");
Content markerAnchor = HtmlTree.A(configuration.htmlVersion, anchorName, anchorContent);
return markerAnchor;
}
Returns a packagename content.
Params: - packageElement – the package to check
Returns: package name content
/**
* Returns a packagename content.
*
* @param packageElement the package to check
* @return package name content
*/
public Content getPackageName(PackageElement packageElement) {
return packageElement == null || packageElement.isUnnamed()
? contents.defaultPackageLabel
: getPackageLabel(packageElement.getQualifiedName());
}
Returns a package name label.
Params: - packageName – the package name
Returns: the package name content
/**
* Returns a package name label.
*
* @param packageName the package name
* @return the package name content
*/
public Content getPackageLabel(CharSequence packageName) {
return new StringContent(packageName);
}
Return the path to the class page for a typeElement.
Params: - te – TypeElement for which the path is requested.
- name – Name of the file(doesn't include path).
/**
* Return the path to the class page for a typeElement.
*
* @param te TypeElement for which the path is requested.
* @param name Name of the file(doesn't include path).
*/
protected DocPath pathString(TypeElement te, DocPath name) {
return pathString(utils.containingPackage(te), name);
}
Return path to the given file name in the given package. So if the name
passed is "Object.html" and the name of the package is "java.lang", and
if the relative path is "../.." then returned string will be
"../../java/lang/Object.html"
Params: - packageElement – Package in which the file name is assumed to be.
- name – File name, to which path string is.
/**
* Return path to the given file name in the given package. So if the name
* passed is "Object.html" and the name of the package is "java.lang", and
* if the relative path is "../.." then returned string will be
* "../../java/lang/Object.html"
*
* @param packageElement Package in which the file name is assumed to be.
* @param name File name, to which path string is.
*/
protected DocPath pathString(PackageElement packageElement, DocPath name) {
return pathToRoot.resolve(DocPath.forPackage(packageElement).resolve(name));
}
Given a package, return the name to be used in HTML anchor tag.
Params: - packageElement – the package.
Returns: the name to be used in HTML anchor tag.
/**
* Given a package, return the name to be used in HTML anchor tag.
* @param packageElement the package.
* @return the name to be used in HTML anchor tag.
*/
public String getPackageAnchorName(PackageElement packageElement) {
return packageElement == null || packageElement.isUnnamed()
? SectionName.UNNAMED_PACKAGE_ANCHOR.getName()
: utils.getPackageName(packageElement);
}
Return the link to the given package.
Params: - packageElement – the package to link to.
- label – the label for the link.
Returns: a content tree for the package link.
/**
* Return the link to the given package.
*
* @param packageElement the package to link to.
* @param label the label for the link.
* @return a content tree for the package link.
*/
public Content getPackageLink(PackageElement packageElement, CharSequence label) {
return getPackageLink(packageElement, new StringContent(label));
}
public Content getPackageLink(PackageElement packageElement) {
StringContent content = packageElement.isUnnamed()
? new StringContent()
: new StringContent(utils.getPackageName(packageElement));
return getPackageLink(packageElement, content);
}
Return the link to the given package.
Params: - packageElement – the package to link to.
- label – the label for the link.
Returns: a content tree for the package link.
/**
* Return the link to the given package.
*
* @param packageElement the package to link to.
* @param label the label for the link.
* @return a content tree for the package link.
*/
public Content getPackageLink(PackageElement packageElement, Content label) {
boolean included = packageElement != null && utils.isIncluded(packageElement);
if (!included) {
for (PackageElement p : configuration.packages) {
if (p.equals(packageElement)) {
included = true;
break;
}
}
}
if (included || packageElement == null) {
return getHyperLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY),
label);
} else {
DocLink crossPkgLink = getCrossPackageLink(utils.getPackageName(packageElement));
if (crossPkgLink != null) {
return getHyperLink(crossPkgLink, label);
} else {
return label;
}
}
}
Get Module link.
Params: - mdle – the module being documented
- label – tag for the link
Returns: a content for the module link
/**
* Get Module link.
*
* @param mdle the module being documented
* @param label tag for the link
* @return a content for the module link
*/
public Content getModuleLink(ModuleElement mdle, Content label) {
boolean included = utils.isIncluded(mdle);
return (included)
? getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(mdle)), label, "", "")
: label;
}
public Content interfaceName(TypeElement typeElement, boolean qual) {
Content name = new StringContent((qual)
? typeElement.getQualifiedName()
: utils.getSimpleName(typeElement));
return (utils.isInterface(typeElement)) ? HtmlTree.SPAN(HtmlStyle.interfaceName, name) : name;
}
Add the link to the content tree.
Params: - typeElement – program element typeElement for which the link will be added
- label – label for the link
- htmltree – the content tree to which the link will be added
/**
* Add the link to the content tree.
*
* @param typeElement program element typeElement for which the link will be added
* @param label label for the link
* @param htmltree the content tree to which the link will be added
*/
public void addSrcLink(Element typeElement, Content label, Content htmltree) {
if (typeElement == null) {
return;
}
TypeElement te = utils.getEnclosingTypeElement(typeElement);
if (te == null) {
// must be a typeElement since in has no containing class.
te = (TypeElement) typeElement;
}
DocPath href = pathToRoot
.resolve(DocPaths.SOURCE_OUTPUT)
.resolve(DocPath.forClass(utils, te));
Content linkContent = getHyperLink(href
.fragment(SourceToHTMLConverter.getAnchorName(utils, typeElement)), label, "", "");
htmltree.addContent(linkContent);
}
Return the link to the given class.
Params: - linkInfo – the information about the link.
Returns: the link for the given class.
/**
* Return the link to the given class.
*
* @param linkInfo the information about the link.
*
* @return the link for the given class.
*/
public Content getLink(LinkInfoImpl linkInfo) {
LinkFactoryImpl factory = new LinkFactoryImpl(this);
return factory.getLink(linkInfo);
}
Return the type parameters for the given class.
Params: - linkInfo – the information about the link.
Returns: the type for the given class.
/**
* Return the type parameters for the given class.
*
* @param linkInfo the information about the link.
* @return the type for the given class.
*/
public Content getTypeParameterLinks(LinkInfoImpl linkInfo) {
LinkFactoryImpl factory = new LinkFactoryImpl(this);
return factory.getTypeParameterLinks(linkInfo, false);
}
Return a class cross link to external class documentation.
The name must be fully qualified to determine which package
the class is in. The -link option does not allow users to
link to external classes in the "default" package.
Params: - qualifiedClassName – the qualified name of the external class.
- refMemName – the name of the member being referenced. This should
be null or empty string if no member is being referenced.
- label – the label for the external link.
- strong – true if the link should be strong.
- style – the style of the link.
- code – true if the label should be code font.
/*************************************************************
* Return a class cross link to external class documentation.
* The name must be fully qualified to determine which package
* the class is in. The -link option does not allow users to
* link to external classes in the "default" package.
*
* @param qualifiedClassName the qualified name of the external class.
* @param refMemName the name of the member being referenced. This should
* be null or empty string if no member is being referenced.
* @param label the label for the external link.
* @param strong true if the link should be strong.
* @param style the style of the link.
* @param code true if the label should be code font.
*/
public Content getCrossClassLink(String qualifiedClassName, String refMemName,
Content label, boolean strong, String style,
boolean code) {
String className = "";
String packageName = qualifiedClassName == null ? "" : qualifiedClassName;
int periodIndex;
while ((periodIndex = packageName.lastIndexOf('.')) != -1) {
className = packageName.substring(periodIndex + 1, packageName.length()) +
(className.length() > 0 ? "." + className : "");
Content defaultLabel = new StringContent(className);
if (code)
defaultLabel = HtmlTree.CODE(defaultLabel);
packageName = packageName.substring(0, periodIndex);
if (getCrossPackageLink(packageName) != null) {
/*
The package exists in external documentation, so link to the external
class (assuming that it exists). This is definitely a limitation of
the -link option. There are ways to determine if an external package
exists, but no way to determine if the external class exists. We just
have to assume that it does.
*/
DocLink link = configuration.extern.getExternalLink(packageName, pathToRoot,
className + ".html", refMemName);
return getHyperLink(link,
(label == null) || label.isEmpty() ? defaultLabel : label,
strong, style,
configuration.getText("doclet.Href_Class_Or_Interface_Title", packageName),
"");
}
}
return null;
}
public boolean isClassLinkable(TypeElement typeElement) {
if (utils.isIncluded(typeElement)) {
return configuration.isGeneratedDoc(typeElement);
}
return configuration.extern.isExternal(typeElement);
}
public DocLink getCrossPackageLink(String pkgName) {
return configuration.extern.getExternalLink(pkgName, pathToRoot,
DocPaths.PACKAGE_SUMMARY.getPath());
}
Get the class link.
Params: - context – the id of the context where the link will be added
- element – to link to
Returns: a content tree for the link
/**
* Get the class link.
*
* @param context the id of the context where the link will be added
* @param element to link to
* @return a content tree for the link
*/
public Content getQualifiedClassLink(LinkInfoImpl.Kind context, Element element) {
LinkInfoImpl linkInfoImpl = new LinkInfoImpl(configuration, context, (TypeElement)element);
return getLink(linkInfoImpl.label(utils.getFullyQualifiedName(element)));
}
Add the class link.
Params: - context – the id of the context where the link will be added
- typeElement – to link to
- contentTree – the content tree to which the link will be added
/**
* Add the class link.
*
* @param context the id of the context where the link will be added
* @param typeElement to link to
* @param contentTree the content tree to which the link will be added
*/
public void addPreQualifiedClassLink(LinkInfoImpl.Kind context, TypeElement typeElement, Content contentTree) {
addPreQualifiedClassLink(context, typeElement, false, contentTree);
}
Retrieve the class link with the package portion of the label in
plain text. If the qualifier is excluded, it will not be included in the
link label.
Params: - typeElement – the class to link to.
- isStrong – true if the link should be strong.
Returns: the link with the package portion of the label in plain text.
/**
* Retrieve the class link with the package portion of the label in
* plain text. If the qualifier is excluded, it will not be included in the
* link label.
*
* @param typeElement the class to link to.
* @param isStrong true if the link should be strong.
* @return the link with the package portion of the label in plain text.
*/
public Content getPreQualifiedClassLink(LinkInfoImpl.Kind context,
TypeElement typeElement, boolean isStrong) {
ContentBuilder classlink = new ContentBuilder();
PackageElement pkg = utils.containingPackage(typeElement);
if (pkg != null && ! configuration.shouldExcludeQualifier(pkg.getSimpleName().toString())) {
classlink.addContent(getEnclosingPackageName(typeElement));
}
classlink.addContent(getLink(new LinkInfoImpl(configuration,
context, typeElement).label(utils.getSimpleName(typeElement)).strong(isStrong)));
return classlink;
}
Add the class link with the package portion of the label in
plain text. If the qualifier is excluded, it will not be included in the
link label.
Params: - context – the id of the context where the link will be added
- typeElement – the class to link to
- isStrong – true if the link should be strong
- contentTree – the content tree to which the link with be added
/**
* Add the class link with the package portion of the label in
* plain text. If the qualifier is excluded, it will not be included in the
* link label.
*
* @param context the id of the context where the link will be added
* @param typeElement the class to link to
* @param isStrong true if the link should be strong
* @param contentTree the content tree to which the link with be added
*/
public void addPreQualifiedClassLink(LinkInfoImpl.Kind context,
TypeElement typeElement, boolean isStrong, Content contentTree) {
PackageElement pkg = utils.containingPackage(typeElement);
if(pkg != null && ! configuration.shouldExcludeQualifier(pkg.getSimpleName().toString())) {
contentTree.addContent(getEnclosingPackageName(typeElement));
}
LinkInfoImpl linkinfo = new LinkInfoImpl(configuration, context, typeElement)
.label(utils.getSimpleName(typeElement))
.strong(isStrong);
Content link = getLink(linkinfo);
contentTree.addContent(link);
}
Add the class link, with only class name as the strong link and prefixing
plain package name.
Params: - context – the id of the context where the link will be added
- typeElement – the class to link to
- contentTree – the content tree to which the link with be added
/**
* Add the class link, with only class name as the strong link and prefixing
* plain package name.
*
* @param context the id of the context where the link will be added
* @param typeElement the class to link to
* @param contentTree the content tree to which the link with be added
*/
public void addPreQualifiedStrongClassLink(LinkInfoImpl.Kind context, TypeElement typeElement, Content contentTree) {
addPreQualifiedClassLink(context, typeElement, true, contentTree);
}
Get the link for the given member.
Params: - context – the id of the context where the link will be added
- element – the member being linked to
- label – the label for the link
Returns: a content tree for the element link
/**
* Get the link for the given member.
*
* @param context the id of the context where the link will be added
* @param element the member being linked to
* @param label the label for the link
* @return a content tree for the element link
*/
public Content getDocLink(LinkInfoImpl.Kind context, Element element, CharSequence label) {
return getDocLink(context, utils.getEnclosingTypeElement(element), element,
new StringContent(label));
}
Return the link for the given member.
Params: - context – the id of the context where the link will be printed.
- element – the member being linked to.
- label – the label for the link.
- strong – true if the link should be strong.
Returns: the link for the given member.
/**
* Return the link for the given member.
*
* @param context the id of the context where the link will be printed.
* @param element the member being linked to.
* @param label the label for the link.
* @param strong true if the link should be strong.
* @return the link for the given member.
*/
public Content getDocLink(LinkInfoImpl.Kind context, Element element, CharSequence label,
boolean strong) {
return getDocLink(context, utils.getEnclosingTypeElement(element), element, label, strong);
}
Return the link for the given member.
Params: - context – the id of the context where the link will be printed.
- typeElement – the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments.
- element – the member being linked to.
- label – the label for the link.
- strong – true if the link should be strong.
Returns: the link for the given member.
/**
* Return the link for the given member.
*
* @param context the id of the context where the link will be printed.
* @param typeElement the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments.
* @param element the member being linked to.
* @param label the label for the link.
* @param strong true if the link should be strong.
* @return the link for the given member.
*/
public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element,
CharSequence label, boolean strong) {
return getDocLink(context, typeElement, element, label, strong, false);
}
public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element,
Content label, boolean strong) {
return getDocLink(context, typeElement, element, label, strong, false);
}
Return the link for the given member.
Params: - context – the id of the context where the link will be printed.
- typeElement – the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments.
- element – the member being linked to.
- label – the label for the link.
- strong – true if the link should be strong.
- isProperty – true if the element parameter is a JavaFX property.
Returns: the link for the given member.
/**
* Return the link for the given member.
*
* @param context the id of the context where the link will be printed.
* @param typeElement the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments.
* @param element the member being linked to.
* @param label the label for the link.
* @param strong true if the link should be strong.
* @param isProperty true if the element parameter is a JavaFX property.
* @return the link for the given member.
*/
public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element,
CharSequence label, boolean strong, boolean isProperty) {
return getDocLink(context, typeElement, element, new StringContent(check(label)), strong, isProperty);
}
CharSequence check(CharSequence s) {
Matcher m = IMPROPER_HTML_CHARS.matcher(s);
if (m.matches()) {
throw new IllegalArgumentException(s.toString());
}
return s;
}
public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element,
Content label, boolean strong, boolean isProperty) {
if (! (utils.isIncluded(element) || utils.isLinkable(typeElement))) {
return label;
} else if (utils.isExecutableElement(element)) {
ExecutableElement ee = (ExecutableElement)element;
return getLink(new LinkInfoImpl(configuration, context, typeElement)
.label(label)
.where(getName(getAnchor(ee, isProperty)))
.strong(strong));
} else if (utils.isVariableElement(element) || utils.isTypeElement(element)) {
return getLink(new LinkInfoImpl(configuration, context, typeElement)
.label(label)
.where(getName(element.getSimpleName().toString()))
.strong(strong));
} else {
return label;
}
}
Return the link for the given member.
Params: - context – the id of the context where the link will be added
- typeElement – the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments
- element – the member being linked to
- label – the label for the link
Returns: the link for the given member
/**
* Return the link for the given member.
*
* @param context the id of the context where the link will be added
* @param typeElement the typeElement that we should link to. This is not
necessarily equal to element.containingClass(). We may be
inheriting comments
* @param element the member being linked to
* @param label the label for the link
* @return the link for the given member
*/
public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element,
Content label) {
if (! (utils.isIncluded(element) || utils.isLinkable(typeElement))) {
return label;
} else if (utils.isExecutableElement(element)) {
ExecutableElement emd = (ExecutableElement) element;
return getLink(new LinkInfoImpl(configuration, context, typeElement)
.label(label)
.where(getName(getAnchor(emd))));
} else if (utils.isVariableElement(element) || utils.isTypeElement(element)) {
return getLink(new LinkInfoImpl(configuration, context, typeElement)
.label(label).where(getName(element.getSimpleName().toString())));
} else {
return label;
}
}
public String getAnchor(ExecutableElement executableElement) {
return getAnchor(executableElement, false);
}
public String getAnchor(ExecutableElement executableElement, boolean isProperty) {
if (isProperty) {
return executableElement.getSimpleName().toString();
}
String signature = utils.signature(executableElement);
StringBuilder signatureParsed = new StringBuilder();
int counter = 0;
for (int i = 0; i < signature.length(); i++) {
char c = signature.charAt(i);
if (c == '<') {
counter++;
} else if (c == '>') {
counter--;
} else if (counter == 0) {
signatureParsed.append(c);
}
}
return utils.getSimpleName(executableElement) + signatureParsed.toString();
}
public Content seeTagToContent(Element element, DocTree see) {
Kind kind = see.getKind();
if (!(kind == LINK || kind == SEE || kind == LINK_PLAIN)) {
return new ContentBuilder();
}
CommentHelper ch = utils.getCommentHelper(element);
String tagName = ch.getTagName(see);
String seetext = replaceDocRootDir(utils.normalizeNewlines(ch.getText(see)).toString());
// Check if @see is an href or "string"
if (seetext.startsWith("<") || seetext.startsWith("\"")) {
return new RawHtml(seetext);
}
boolean isLinkPlain = kind == LINK_PLAIN;
Content label = plainOrCode(isLinkPlain, new RawHtml(ch.getLabel(configuration, see)));
//The text from the @see tag. We will output this text when a label is not specified.
Content text = plainOrCode(kind == LINK_PLAIN, new RawHtml(seetext));
TypeElement refClass = ch.getReferencedClass(configuration, see);
String refClassName = ch.getReferencedClassName(configuration, see);
Element refMem = ch.getReferencedMember(configuration, see);
String refMemName = ch.getReferencedMemberName(see);
if (refMemName == null && refMem != null) {
refMemName = refMem.toString();
}
if (refClass == null) {
//@see is not referencing an included class
PackageElement refPackage = ch.getReferencedPackage(configuration, see);
if (refPackage != null && utils.isIncluded(refPackage)) {
//@see is referencing an included package
if (label.isEmpty())
label = plainOrCode(isLinkPlain,
new StringContent(refPackage.getQualifiedName()));
return getPackageLink(refPackage, label);
} else {
// @see is not referencing an included class or package. Check for cross links.
Content classCrossLink;
DocLink packageCrossLink = getCrossPackageLink(refClassName);
if (packageCrossLink != null) {
// Package cross link found
return getHyperLink(packageCrossLink,
(label.isEmpty() ? text : label));
} else if ((classCrossLink = getCrossClassLink(refClassName,
refMemName, label, false, "", !isLinkPlain)) != null) {
// Class cross link found (possibly to a member in the class)
return classCrossLink;
} else {
// No cross link found so print warning
messages.warning(ch.getDocTreePath(see),
"doclet.see.class_or_package_not_found",
"@" + tagName,
seetext);
return (label.isEmpty() ? text: label);
}
}
} else if (refMemName == null) {
// Must be a class reference since refClass is not null and refMemName is null.
if (label.isEmpty()) {
/*
* it seems to me this is the right thing to do, but it causes comparator failures.
*/
if (!configuration.backwardCompatibility) {
StringContent content = utils.isEnclosingPackageIncluded(refClass)
? new StringContent(utils.getSimpleName(refClass))
: new StringContent(utils.getFullyQualifiedName(refClass));
label = plainOrCode(isLinkPlain, content);
} else {
label = plainOrCode(isLinkPlain,
new StringContent(utils.getSimpleName(refClass)));
}
}
return getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, refClass)
.label(label));
} else if (refMem == null) {
// Must be a member reference since refClass is not null and refMemName is not null.
// However, refMem is null, so this referenced member does not exist.
return (label.isEmpty() ? text: label);
} else {
// Must be a member reference since refClass is not null and refMemName is not null.
// refMem is not null, so this @see tag must be referencing a valid member.
TypeElement containing = utils.getEnclosingTypeElement(refMem);
if (ch.getText(see).trim().startsWith("#") &&
! (utils.isPublic(containing) || utils.isLinkable(containing))) {
// Since the link is relative and the holder is not even being
// documented, this must be an inherited link. Redirect it.
// The current class either overrides the referenced member or
// inherits it automatically.
if (this instanceof ClassWriterImpl) {
containing = ((ClassWriterImpl) this).getTypeElement();
} else if (!utils.isPublic(containing)) {
messages.warning(
ch.getDocTreePath(see), "doclet.see.class_or_package_not_accessible",
tagName, utils.getFullyQualifiedName(containing));
} else {
messages.warning(
ch.getDocTreePath(see), "doclet.see.class_or_package_not_found",
tagName, seetext);
}
}
if (configuration.currentTypeElement != containing) {
refMemName = (utils.isConstructor(refMem))
? refMemName
: utils.getSimpleName(containing) + "." + refMemName;
}
if (utils.isExecutableElement(refMem)) {
if (refMemName.indexOf('(') < 0) {
refMemName += utils.makeSignature((ExecutableElement)refMem, true);
}
}
text = plainOrCode(kind == LINK_PLAIN, new StringContent(refMemName));
return getDocLink(LinkInfoImpl.Kind.SEE_TAG, containing,
refMem, (label.isEmpty() ? text: label), false);
}
}
private Content plainOrCode(boolean plain, Content body) {
return (plain || body.isEmpty()) ? body : HtmlTree.CODE(body);
}
Add the inline comment.
Params: - element – the Element for which the inline comment will be added
- tag – the inline tag to be added
- htmltree – the content tree to which the comment will be added
/**
* Add the inline comment.
*
* @param element the Element for which the inline comment will be added
* @param tag the inline tag to be added
* @param htmltree the content tree to which the comment will be added
*/
public void addInlineComment(Element element, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(element);
List<? extends DocTree> description = ch.getDescription(configuration, tag);
addCommentTags(element, tag, description, false, false, htmltree);
}
Get the deprecated phrase as content.
Params: - e – the Element for which the inline deprecated comment will be added
Returns: a content tree for the deprecated phrase.
/**
* Get the deprecated phrase as content.
*
* @param e the Element for which the inline deprecated comment will be added
* @return a content tree for the deprecated phrase.
*/
public Content getDeprecatedPhrase(Element e) {
return (utils.isDeprecatedForRemoval(e))
? contents.deprecatedForRemovalPhrase
: contents.deprecatedPhrase;
}
Add the inline deprecated comment.
Params: - e – the Element for which the inline deprecated comment will be added
- tag – the inline tag to be added
- htmltree – the content tree to which the comment will be added
/**
* Add the inline deprecated comment.
*
* @param e the Element for which the inline deprecated comment will be added
* @param tag the inline tag to be added
* @param htmltree the content tree to which the comment will be added
*/
public void addInlineDeprecatedComment(Element e, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(e);
addCommentTags(e, ch.getBody(configuration, tag), true, false, htmltree);
}
Adds the summary content.
Params: - element – the Element for which the summary will be generated
- htmltree – the documentation tree to which the summary will be added
/**
* Adds the summary content.
*
* @param element the Element for which the summary will be generated
* @param htmltree the documentation tree to which the summary will be added
*/
public void addSummaryComment(Element element, Content htmltree) {
addSummaryComment(element, utils.getFirstSentenceTrees(element), htmltree);
}
Adds the summary content.
Params: - element – the Element for which the summary will be generated
- firstSentenceTags – the first sentence tags for the doc
- htmltree – the documentation tree to which the summary will be added
/**
* Adds the summary content.
*
* @param element the Element for which the summary will be generated
* @param firstSentenceTags the first sentence tags for the doc
* @param htmltree the documentation tree to which the summary will be added
*/
public void addSummaryComment(Element element, List<? extends DocTree> firstSentenceTags, Content htmltree) {
addCommentTags(element, firstSentenceTags, false, true, htmltree);
}
public void addSummaryDeprecatedComment(Element element, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(element);
List<? extends DocTree> body = ch.getBody(configuration, tag);
addCommentTags(element, ch.getFirstSentenceTrees(configuration, body), true, true, htmltree);
}
Adds the inline comment.
Params: - element – the Element for which the inline comments will be generated
- htmltree – the documentation tree to which the inline comments will be added
/**
* Adds the inline comment.
*
* @param element the Element for which the inline comments will be generated
* @param htmltree the documentation tree to which the inline comments will be added
*/
public void addInlineComment(Element element, Content htmltree) {
addCommentTags(element, utils.getFullBody(element), false, false, htmltree);
}
Adds the comment tags.
Params: - element – the Element for which the comment tags will be generated
- tags – the first sentence tags for the doc
- depr – true if it is deprecated
- first – true if the first sentence tags should be added
- htmltree – the documentation tree to which the comment tags will be added
/**
* Adds the comment tags.
*
* @param element the Element for which the comment tags will be generated
* @param tags the first sentence tags for the doc
* @param depr true if it is deprecated
* @param first true if the first sentence tags should be added
* @param htmltree the documentation tree to which the comment tags will be added
*/
private void addCommentTags(Element element, List<? extends DocTree> tags, boolean depr,
boolean first, Content htmltree) {
addCommentTags(element, null, tags, depr, first, htmltree);
}
Adds the comment tags.
Params: - element – for which the comment tags will be generated
- holderTag – the block tag context for the inline tags
- tags – the first sentence tags for the doc
- depr – true if it is deprecated
- first – true if the first sentence tags should be added
- htmltree – the documentation tree to which the comment tags will be added
/**
* Adds the comment tags.
*
* @param element for which the comment tags will be generated
* @param holderTag the block tag context for the inline tags
* @param tags the first sentence tags for the doc
* @param depr true if it is deprecated
* @param first true if the first sentence tags should be added
* @param htmltree the documentation tree to which the comment tags will be added
*/
private void addCommentTags(Element element, DocTree holderTag, List<? extends DocTree> tags, boolean depr,
boolean first, Content htmltree) {
if(configuration.nocomment){
return;
}
Content div;
Content result = commentTagsToContent(null, element, tags, first);
if (depr) {
Content italic = HtmlTree.SPAN(HtmlStyle.deprecationComment, result);
div = HtmlTree.DIV(HtmlStyle.block, italic);
htmltree.addContent(div);
}
else {
div = HtmlTree.DIV(HtmlStyle.block, result);
htmltree.addContent(div);
}
if (tags.isEmpty()) {
htmltree.addContent(Contents.SPACE);
}
}
boolean ignoreNonInlineTag(DocTree dtree) {
Name name = null;
if (dtree.getKind() == Kind.START_ELEMENT) {
StartElementTree setree = (StartElementTree)dtree;
name = setree.getName();
} else if (dtree.getKind() == Kind.END_ELEMENT) {
EndElementTree eetree = (EndElementTree)dtree;
name = eetree.getName();
}
if (name != null) {
com.sun.tools.doclint.HtmlTag htmlTag = com.sun.tools.doclint.HtmlTag.get(name);
if (htmlTag != null &&
htmlTag.blockType != com.sun.tools.doclint.HtmlTag.BlockType.INLINE) {
return true;
}
}
return false;
}
boolean isAllWhiteSpace(String body) {
for (int i = 0 ; i < body.length(); i++) {
if (!Character.isWhitespace(body.charAt(i)))
return false;
}
return true;
}
Converts inline tags and text to text strings, expanding the
inline tags along the way. Called wherever text can contain
an inline tag, such as in comments or in free-form text arguments
to non-inline tags.
Params: - holderTag – specific tag where comment resides
- element – specific element where comment resides
- tags – array of text tags and inline tags (often alternating)
present in the text of interest for this element
- isFirstSentence – true if text is first sentence
Returns: a Content object
/**
* Converts inline tags and text to text strings, expanding the
* inline tags along the way. Called wherever text can contain
* an inline tag, such as in comments or in free-form text arguments
* to non-inline tags.
*
* @param holderTag specific tag where comment resides
* @param element specific element where comment resides
* @param tags array of text tags and inline tags (often alternating)
present in the text of interest for this element
* @param isFirstSentence true if text is first sentence
* @return a Content object
*/
public Content commentTagsToContent(DocTree holderTag, Element element,
List<? extends DocTree> tags, boolean isFirstSentence) {
final Content result = new ContentBuilder() {
@Override
public void addContent(CharSequence text) {
super.addContent(utils.normalizeNewlines(text));
}
};
CommentHelper ch = utils.getCommentHelper(element);
// Array of all possible inline tags for this javadoc run
configuration.tagletManager.checkTags(utils, element, tags, true);
for (ListIterator<? extends DocTree> iterator = tags.listIterator(); iterator.hasNext();) {
DocTree tag = iterator.next();
// zap block tags
if (isFirstSentence && ignoreNonInlineTag(tag))
continue;
if (isFirstSentence && iterator.nextIndex() == tags.size() &&
(tag.getKind() == TEXT && isAllWhiteSpace(ch.getText(tag))))
continue;
boolean allDone = new SimpleDocTreeVisitor<Boolean, Content>() {
// notify the next DocTree handler to take necessary action
boolean commentRemoved = false;
private boolean isLast(DocTree node) {
return node.equals(tags.get(tags.size() - 1));
}
private boolean isFirst(DocTree node) {
return node.equals(tags.get(0));
}
private boolean inAnAtag() {
if (utils.isStartElement(tag)) {
StartElementTree st = (StartElementTree)tag;
Name name = st.getName();
if (name != null) {
com.sun.tools.doclint.HtmlTag htag =
com.sun.tools.doclint.HtmlTag.get(name);
return htag != null && htag.equals(com.sun.tools.doclint.HtmlTag.A);
}
}
return false;
}
@Override
public Boolean visitAttribute(AttributeTree node, Content c) {
StringBuilder sb = new StringBuilder(SPACER).append(node.getName());
if (node.getValueKind() == ValueKind.EMPTY) {
result.addContent(sb);
return false;
}
sb.append("=");
String quote;
switch (node.getValueKind()) {
case DOUBLE:
quote = "\"";
break;
case SINGLE:
quote = "\'";
break;
default:
quote = "";
break;
}
sb.append(quote);
result.addContent(sb);
Content docRootContent = new ContentBuilder();
for (DocTree dt : node.getValue()) {
if (utils.isText(dt) && inAnAtag()) {
String text = ((TextTree) dt).getBody();
if (text.startsWith("/..") && !configuration.docrootparent.isEmpty()) {
result.addContent(configuration.docrootparent);
docRootContent = new ContentBuilder();
result.addContent(textCleanup(text.substring(3), isLast(node)));
} else {
if (!docRootContent.isEmpty()) {
docRootContent = copyDocRootContent(docRootContent);
} else {
text = redirectRelativeLinks(element, (TextTree) dt);
}
result.addContent(textCleanup(text, isLast(node)));
}
} else {
docRootContent = copyDocRootContent(docRootContent);
dt.accept(this, docRootContent);
}
}
copyDocRootContent(docRootContent);
result.addContent(quote);
return false;
}
@Override
public Boolean visitComment(CommentTree node, Content c) {
if (isFirstSentence && isFirst(node)) {
commentRemoved = true;
return this.visit(iterator.next(), c);
}
result.addContent(new RawHtml(node.getBody()));
return false;
}
private Content copyDocRootContent(Content content) {
if (!content.isEmpty()) {
result.addContent(content);
return new ContentBuilder();
}
return content;
}
@Override
public Boolean visitDocRoot(DocRootTree node, Content c) {
Content docRootContent = TagletWriter.getInlineTagOutput(element,
configuration.tagletManager,
holderTag,
node,
getTagletWriterInstance(isFirstSentence));
if (c != null) {
c.addContent(docRootContent);
} else {
result.addContent(docRootContent);
}
return false;
}
@Override
public Boolean visitEndElement(EndElementTree node, Content c) {
RawHtml rawHtml = new RawHtml("</" + node.getName() + ">");
result.addContent(rawHtml);
return false;
}
@Override
public Boolean visitEntity(EntityTree node, Content c) {
result.addContent(new RawHtml(node.toString()));
return false;
}
@Override
public Boolean visitErroneous(ErroneousTree node, Content c) {
messages.warning(ch.getDocTreePath(node),
"doclet.tag.invalid_usage", node);
result.addContent(new RawHtml(node.toString()));
return false;
}
@Override
public Boolean visitInheritDoc(InheritDocTree node, Content c) {
Content output = TagletWriter.getInlineTagOutput(element,
configuration.tagletManager, holderTag,
tag, getTagletWriterInstance(isFirstSentence));
result.addContent(output);
// if we obtained the first sentence successfully, nothing more to do
return (isFirstSentence && !output.isEmpty());
}
@Override
public Boolean visitIndex(IndexTree node, Content p) {
Content output = TagletWriter.getInlineTagOutput(element,
configuration.tagletManager, holderTag, tag,
getTagletWriterInstance(isFirstSentence));
if (output != null) {
result.addContent(output);
}
return false;
}
@Override
public Boolean visitLink(LinkTree node, Content c) {
// we need to pass the DocTreeImpl here, so ignore node
result.addContent(seeTagToContent(element, tag));
return false;
}
@Override
public Boolean visitLiteral(LiteralTree node, Content c) {
String s = node.getBody().toString();
Content content = new StringContent(utils.normalizeNewlines(s));
if (node.getKind() == CODE)
content = HtmlTree.CODE(content);
result.addContent(content);
return false;
}
@Override
public Boolean visitSee(SeeTree node, Content c) {
// we need to pass the DocTreeImpl here, so ignore node
result.addContent(seeTagToContent(element, tag));
return false;
}
@Override
public Boolean visitStartElement(StartElementTree node, Content c) {
String text = "<" + node.getName();
RawHtml rawHtml = new RawHtml(utils.normalizeNewlines(text));
result.addContent(rawHtml);
for (DocTree dt : node.getAttributes()) {
dt.accept(this, null);
}
result.addContent(new RawHtml(node.isSelfClosing() ? "/>" : ">"));
return false;
}
private CharSequence textCleanup(String text, boolean isLast) {
return textCleanup(text, isLast, false);
}
private CharSequence textCleanup(String text, boolean isLast, boolean trimLeader) {
if (trimLeader) {
text = removeLeadingWhitespace(text);
}
if (isFirstSentence && isLast) {
text = removeTrailingWhitespace(text);
}
text = utils.replaceTabs(text);
return utils.normalizeNewlines(text);
}
@Override
public Boolean visitText(TextTree node, Content c) {
String text = node.getBody();
result.addContent(new RawHtml(textCleanup(text, isLast(node), commentRemoved)));
commentRemoved = false;
return false;
}
@Override
protected Boolean defaultAction(DocTree node, Content c) {
Content output = TagletWriter.getInlineTagOutput(element,
configuration.tagletManager, holderTag, tag,
getTagletWriterInstance(isFirstSentence));
if (output != null) {
result.addContent(output);
}
return false;
}
}.visit(tag, null);
if (allDone)
break;
}
return result;
}
private String removeTrailingWhitespace(String text) {
char[] buf = text.toCharArray();
for (int i = buf.length - 1; i > 0 ; i--) {
if (!Character.isWhitespace(buf[i]))
return text.substring(0, i + 1);
}
return text;
}
private String removeLeadingWhitespace(String text) {
char[] buf = text.toCharArray();
for (int i = 0; i < buf.length; i++) {
if (!Character.isWhitespace(buf[i])) {
return text.substring(i);
}
}
return text;
}
Return true if relative links should not be redirected.
Returns: Return true if a relative link should not be redirected.
/**
* Return true if relative links should not be redirected.
*
* @return Return true if a relative link should not be redirected.
*/
private boolean shouldNotRedirectRelativeLinks() {
return this instanceof AnnotationTypeWriter ||
this instanceof ClassWriter ||
this instanceof PackageSummaryWriter;
}
Suppose a piece of documentation has a relative link. When you copy
that documentation to another place such as the index or class-use page,
that relative link will no longer work. We should redirect those links
so that they will work again.
Here is the algorithm used to fix the link:
<relative link> => docRoot + <relative path to file> + <relative link>
For example, suppose DocletEnvironment has this link: <a href="package-summary.html">The package Page</a>
If this link appeared in the index, we would redirect the link like this: <a href="./com/sun/javadoc/package-summary.html">The package Page</a>
Params: - element – the Element object whose documentation is being written.
- text – the text being written.
Returns: the text, with all the relative links redirected to work.
/**
* Suppose a piece of documentation has a relative link. When you copy
* that documentation to another place such as the index or class-use page,
* that relative link will no longer work. We should redirect those links
* so that they will work again.
* <p>
* Here is the algorithm used to fix the link:
* <p>
* {@literal <relative link> => docRoot + <relative path to file> + <relative link> }
* <p>
* For example, suppose DocletEnvironment has this link:
* {@literal <a href="package-summary.html">The package Page</a> }
* <p>
* If this link appeared in the index, we would redirect
* the link like this:
*
* {@literal <a href="./com/sun/javadoc/package-summary.html">The package Page</a>}
*
* @param element the Element object whose documentation is being written.
* @param text the text being written.
*
* @return the text, with all the relative links redirected to work.
*/
private String redirectRelativeLinks(Element element, TextTree tt) {
String text = tt.getBody();
if (element == null || utils.isOverviewElement(element) || shouldNotRedirectRelativeLinks()) {
return text;
}
DocPath redirectPathFromRoot = new SimpleElementVisitor9<DocPath, Void>() {
@Override
public DocPath visitType(TypeElement e, Void p) {
return DocPath.forPackage(utils.containingPackage(e));
}
@Override
public DocPath visitPackage(PackageElement e, Void p) {
return DocPath.forPackage(e);
}
@Override
public DocPath visitVariable(VariableElement e, Void p) {
return DocPath.forPackage(utils.containingPackage(e));
}
@Override
public DocPath visitExecutable(ExecutableElement e, Void p) {
return DocPath.forPackage(utils.containingPackage(e));
}
@Override
protected DocPath defaultAction(Element e, Void p) {
return null;
}
}.visit(element);
if (redirectPathFromRoot == null) {
return text;
}
String lower = Utils.toLowerCase(text);
if (!(lower.startsWith("mailto:")
|| lower.startsWith("http:")
|| lower.startsWith("https:")
|| lower.startsWith("file:"))) {
text = "{@" + (new DocRootTaglet()).getName() + "}/"
+ redirectPathFromRoot.resolve(text).getPath();
text = replaceDocRootDir(text);
}
return text;
}
static final Set<String> blockTags = new HashSet<>();
static {
for (HtmlTag t: HtmlTag.values()) {
if (t.blockType == HtmlTag.BlockType.BLOCK)
blockTags.add(t.value);
}
}
Add a link to the stylesheet file.
Params: - head – the content tree to which the files will be added
/**
* Add a link to the stylesheet file.
*
* @param head the content tree to which the files will be added
*/
public void addStyleSheetProperties(Content head) {
String stylesheetfile = configuration.stylesheetfile;
DocPath stylesheet;
if (stylesheetfile.isEmpty()) {
stylesheet = DocPaths.STYLESHEET;
} else {
DocFile file = DocFile.createFileForInput(configuration, stylesheetfile);
stylesheet = DocPath.create(file.getName());
}
HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
pathToRoot.resolve(stylesheet).getPath(),
"Style");
head.addContent(link);
if (configuration.createindex) {
HtmlTree jq_link = HtmlTree.LINK("stylesheet", "text/css",
pathToRoot.resolve(DocPaths.JQUERY_FILES.resolve(DocPaths.JQUERY_STYLESHEET_FILE)).getPath(),
"Style");
head.addContent(jq_link);
}
}
Add a link to the JavaScript file.
Params: - head – the content tree to which the files will be added
/**
* Add a link to the JavaScript file.
*
* @param head the content tree to which the files will be added
*/
public void addScriptProperties(Content head) {
HtmlTree javascript = HtmlTree.SCRIPT(pathToRoot.resolve(DocPaths.JAVASCRIPT).getPath());
head.addContent(javascript);
if (configuration.createindex) {
if (pathToRoot != null && script != null) {
String ptrPath = pathToRoot.isEmpty() ? "." : pathToRoot.getPath();
script.addContent(new RawHtml("var pathtoroot = \"" + ptrPath + "/\";loadScripts(document, \'script\');"));
}
addJQueryFile(head, DocPaths.JSZIP_MIN);
addJQueryFile(head, DocPaths.JSZIPUTILS_MIN);
head.addContent(new RawHtml("<!--[if IE]>"));
addJQueryFile(head, DocPaths.JSZIPUTILS_IE_MIN);
head.addContent(new RawHtml("<![endif]-->"));
addJQueryFile(head, DocPaths.JQUERY_JS_1_10);
addJQueryFile(head, DocPaths.JQUERY_JS);
}
}
Add a link to the JQuery javascript file.
Params: - head – the content tree to which the files will be added
- filePath – the DocPath of the file that needs to be added
/**
* Add a link to the JQuery javascript file.
*
* @param head the content tree to which the files will be added
* @param filePath the DocPath of the file that needs to be added
*/
private void addJQueryFile(Content head, DocPath filePath) {
HtmlTree jqyeryScriptFile = HtmlTree.SCRIPT(
pathToRoot.resolve(DocPaths.JQUERY_FILES.resolve(filePath)).getPath());
head.addContent(jqyeryScriptFile);
}
According to
The Java™ Language Specification,
all the outer classes and static nested classes are core classes.
/**
* According to
* <cite>The Java™ Language Specification</cite>,
* all the outer classes and static nested classes are core classes.
*/
public boolean isCoreClass(TypeElement typeElement) {
return utils.getEnclosingTypeElement(typeElement) == null || utils.isStatic(typeElement);
}
Adds the annotation types for the given packageElement.
Params: - packageElement – the package to write annotations for.
- htmltree – the documentation tree to which the annotation info will be
added
/**
* Adds the annotation types for the given packageElement.
*
* @param packageElement the package to write annotations for.
* @param htmltree the documentation tree to which the annotation info will be
* added
*/
public void addAnnotationInfo(PackageElement packageElement, Content htmltree) {
addAnnotationInfo(packageElement, packageElement.getAnnotationMirrors(), htmltree);
}
Add the annotation types of the executable receiver.
Params: - method – the executable to write the receiver annotations for.
- descList – list of annotation description.
- htmltree – the documentation tree to which the annotation info will be
added
/**
* Add the annotation types of the executable receiver.
*
* @param method the executable to write the receiver annotations for.
* @param descList list of annotation description.
* @param htmltree the documentation tree to which the annotation info will be
* added
*/
public void addReceiverAnnotationInfo(ExecutableElement method, List<AnnotationMirror> descList,
Content htmltree) {
addAnnotationInfo(0, method, descList, false, htmltree);
}
/*
* this is a hack to delay dealing with Annotations in the writers, the assumption
* is that all necessary checks have been made to get here.
*/
public void addReceiverAnnotationInfo(ExecutableElement method, TypeMirror rcvrTypeMirror,
List<? extends AnnotationMirror> annotationMirrors, Content htmltree) {
TypeMirror rcvrType = method.getReceiverType();
List<? extends AnnotationMirror> annotationMirrors1 = rcvrType.getAnnotationMirrors();
addAnnotationInfo(0, method, annotationMirrors1, false, htmltree);
}
Adds the annotatation types for the given element.
Params: - element – the package to write annotations for
- htmltree – the content tree to which the annotation types will be added
/**
* Adds the annotatation types for the given element.
*
* @param element the package to write annotations for
* @param htmltree the content tree to which the annotation types will be added
*/
public void addAnnotationInfo(Element element, Content htmltree) {
addAnnotationInfo(element, element.getAnnotationMirrors(), htmltree);
}
Add the annotatation types for the given element and parameter.
Params: - indent – the number of spaces to indent the parameters.
- element – the element to write annotations for.
- param – the parameter to write annotations for.
- tree – the content tree to which the annotation types will be added
/**
* Add the annotatation types for the given element and parameter.
*
* @param indent the number of spaces to indent the parameters.
* @param element the element to write annotations for.
* @param param the parameter to write annotations for.
* @param tree the content tree to which the annotation types will be added
*/
public boolean addAnnotationInfo(int indent, Element element, VariableElement param,
Content tree) {
return addAnnotationInfo(indent, element, param.getAnnotationMirrors(), false, tree);
}
Adds the annotatation types for the given Element.
Params: - element – the element to write annotations for.
- descList – the array of
AnnotationDesc
. - htmltree – the documentation tree to which the annotation info will be
added
/**
* Adds the annotatation types for the given Element.
*
* @param element the element to write annotations for.
* @param descList the array of {@link AnnotationDesc}.
* @param htmltree the documentation tree to which the annotation info will be
* added
*/
private void addAnnotationInfo(Element element, List<? extends AnnotationMirror> descList,
Content htmltree) {
addAnnotationInfo(0, element, descList, true, htmltree);
}
Adds the annotation types for the given element.
Params: - indent – the number of extra spaces to indent the annotations.
- element – the element to write annotations for.
- descList – the array of
AnnotationDesc
. - htmltree – the documentation tree to which the annotation info will be
added
/**
* Adds the annotation types for the given element.
*
* @param indent the number of extra spaces to indent the annotations.
* @param element the element to write annotations for.
* @param descList the array of {@link AnnotationDesc}.
* @param htmltree the documentation tree to which the annotation info will be
* added
*/
private boolean addAnnotationInfo(int indent, Element element,
List<? extends AnnotationMirror> descList, boolean lineBreak, Content htmltree) {
List<Content> annotations = getAnnotations(indent, descList, lineBreak);
String sep = "";
if (annotations.isEmpty()) {
return false;
}
for (Content annotation: annotations) {
htmltree.addContent(sep);
htmltree.addContent(annotation);
if (!lineBreak) {
sep = " ";
}
}
return true;
}
Return the string representations of the annotation types for
the given doc.
Params: - indent – the number of extra spaces to indent the annotations.
- descList – the array of
AnnotationDesc
. - linkBreak – if true, add new line between each member value.
Returns: an array of strings representing the annotations being
documented.
/**
* Return the string representations of the annotation types for
* the given doc.
*
* @param indent the number of extra spaces to indent the annotations.
* @param descList the array of {@link AnnotationDesc}.
* @param linkBreak if true, add new line between each member value.
* @return an array of strings representing the annotations being
* documented.
*/
private List<Content> getAnnotations(int indent, List<? extends AnnotationMirror> descList, boolean linkBreak) {
return getAnnotations(indent, descList, linkBreak, true);
}
private List<Content> getAnnotations(int indent, AnnotationMirror amirror, boolean linkBreak) {
List<AnnotationMirror> descList = new ArrayList<>();
descList.add(amirror);
return getAnnotations(indent, descList, linkBreak, true);
}
Return the string representations of the annotation types for the given doc. A null
elementType
indicates that all the annotations should be returned without any filtering. Params: - indent – the number of extra spaces to indent the annotations.
- descList – the array of
AnnotationDesc
. - linkBreak – if true, add new line between each member value.
- isJava5DeclarationLocation –
Returns: an array of strings representing the annotations being
documented.
/**
* Return the string representations of the annotation types for
* the given doc.
*
* A {@code null} {@code elementType} indicates that all the
* annotations should be returned without any filtering.
*
* @param indent the number of extra spaces to indent the annotations.
* @param descList the array of {@link AnnotationDesc}.
* @param linkBreak if true, add new line between each member value.
* @param isJava5DeclarationLocation
* @return an array of strings representing the annotations being
* documented.
*/
public List<Content> getAnnotations(int indent, List<? extends AnnotationMirror> descList,
boolean linkBreak, boolean isJava5DeclarationLocation) {
List<Content> results = new ArrayList<>();
ContentBuilder annotation;
for (AnnotationMirror aDesc : descList) {
TypeElement annotationElement = (TypeElement)aDesc.getAnnotationType().asElement();
// If an annotation is not documented, do not add it to the list. If
// the annotation is of a repeatable type, and if it is not documented
// and also if its container annotation is not documented, do not add it
// to the list. If an annotation of a repeatable type is not documented
// but its container is documented, it will be added to the list.
if (!utils.isDocumentedAnnotation(annotationElement) &&
(!isAnnotationDocumented && !isContainerDocumented)) {
continue;
}
/* TODO: check logic here to correctly handle declaration
* and type annotations.
if (utils.isDeclarationAnnotation(annotationElement, isJava5DeclarationLocation)) {
continue;
}*/
annotation = new ContentBuilder();
isAnnotationDocumented = false;
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.ANNOTATION, annotationElement);
Map<? extends ExecutableElement, ? extends AnnotationValue> pairs = aDesc.getElementValues();
// If the annotation is synthesized, do not print the container.
if (utils.configuration.workArounds.isSynthesized(aDesc)) {
for (ExecutableElement ee : pairs.keySet()) {
AnnotationValue annotationValue = pairs.get(ee);
List<AnnotationValue> annotationTypeValues = new ArrayList<>();
new SimpleAnnotationValueVisitor9<Void, List<AnnotationValue>>() {
@Override
public Void visitArray(List<? extends AnnotationValue> vals, List<AnnotationValue> p) {
p.addAll(vals);
return null;
}
@Override
protected Void defaultAction(Object o, List<AnnotationValue> p) {
p.add(annotationValue);
return null;
}
}.visit(annotationValue, annotationTypeValues);
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
annotation.addContent(sep);
annotation.addContent(annotationValueToContent(av));
sep = " ";
}
}
} else if (isAnnotationArray(pairs)) {
// If the container has 1 or more value defined and if the
// repeatable type annotation is not documented, do not print
// the container.
if (pairs.size() == 1 && isAnnotationDocumented) {
List<AnnotationValue> annotationTypeValues = new ArrayList<>();
for (AnnotationValue a : pairs.values()) {
new SimpleAnnotationValueVisitor9<Void, List<AnnotationValue>>() {
@Override
public Void visitArray(List<? extends AnnotationValue> vals, List<AnnotationValue> annotationTypeValues) {
for (AnnotationValue av : vals) {
annotationTypeValues.add(av);
}
return null;
}
}.visit(a, annotationTypeValues);
}
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
annotation.addContent(sep);
annotation.addContent(annotationValueToContent(av));
sep = " ";
}
}
// If the container has 1 or more value defined and if the
// repeatable type annotation is not documented, print the container.
else {
addAnnotations(annotationElement, linkInfo, annotation, pairs,
indent, false);
}
}
else {
addAnnotations(annotationElement, linkInfo, annotation, pairs,
indent, linkBreak);
}
annotation.addContent(linkBreak ? DocletConstants.NL : "");
results.add(annotation);
}
return results;
}
Add annotation to the annotation string.
Params: - annotationDoc – the annotation being documented
- linkInfo – the information about the link
- annotation – the annotation string to which the annotation will be added
- pairs – annotation type element and value pairs
- indent – the number of extra spaces to indent the annotations.
- linkBreak – if true, add new line between each member value
/**
* Add annotation to the annotation string.
*
* @param annotationDoc the annotation being documented
* @param linkInfo the information about the link
* @param annotation the annotation string to which the annotation will be added
* @param pairs annotation type element and value pairs
* @param indent the number of extra spaces to indent the annotations.
* @param linkBreak if true, add new line between each member value
*/
private void addAnnotations(TypeElement annotationDoc, LinkInfoImpl linkInfo,
ContentBuilder annotation, Map<? extends ExecutableElement,? extends AnnotationValue>map,
int indent, boolean linkBreak) {
linkInfo.label = new StringContent("@");
linkInfo.label.addContent(annotationDoc.getSimpleName());
annotation.addContent(getLink(linkInfo));
if (!map.isEmpty()) {
annotation.addContent("(");
boolean isFirst = true;
Set<? extends ExecutableElement> keys = map.keySet();
boolean multipleValues = keys.size() > 1;
for (ExecutableElement element : keys) {
if (isFirst) {
isFirst = false;
} else {
annotation.addContent(",");
if (linkBreak) {
annotation.addContent(DocletConstants.NL);
int spaces = annotationDoc.getSimpleName().length() + 2;
for (int k = 0; k < (spaces + indent); k++) {
annotation.addContent(" ");
}
}
}
String simpleName = element.getSimpleName().toString();
if (multipleValues || !"value".equals(simpleName)) { // Omit "value=" where unnecessary
annotation.addContent(getDocLink(LinkInfoImpl.Kind.ANNOTATION,
element, simpleName, false));
annotation.addContent("=");
}
AnnotationValue annotationValue = map.get(element);
List<AnnotationValue> annotationTypeValues = new ArrayList<>();
new SimpleAnnotationValueVisitor9<Void, AnnotationValue>() {
@Override
public Void visitArray(List<? extends AnnotationValue> vals, AnnotationValue p) {
annotationTypeValues.addAll(vals);
return null;
}
@Override
protected Void defaultAction(Object o, AnnotationValue p) {
annotationTypeValues.add(p);
return null;
}
}.visit(annotationValue, annotationValue);
annotation.addContent(annotationTypeValues.size() == 1 ? "" : "{");
String sep = "";
for (AnnotationValue av : annotationTypeValues) {
annotation.addContent(sep);
annotation.addContent(annotationValueToContent(av));
sep = ",";
}
annotation.addContent(annotationTypeValues.size() == 1 ? "" : "}");
isContainerDocumented = false;
}
annotation.addContent(")");
}
}
Check if the annotation contains an array of annotation as a value. This
check is to verify if a repeatable type annotation is present or not.
Params: - pairs – annotation type element and value pairs
Returns: true if the annotation contains an array of annotation as a value.
/**
* Check if the annotation contains an array of annotation as a value. This
* check is to verify if a repeatable type annotation is present or not.
*
* @param pairs annotation type element and value pairs
*
* @return true if the annotation contains an array of annotation as a value.
*/
private boolean isAnnotationArray(Map<? extends ExecutableElement, ? extends AnnotationValue> pairs) {
AnnotationValue annotationValue;
for (ExecutableElement ee : pairs.keySet()) {
annotationValue = pairs.get(ee);
boolean rvalue = new SimpleAnnotationValueVisitor9<Boolean, Void>() {
@Override
public Boolean visitArray(List<? extends AnnotationValue> vals, Void p) {
if (vals.size() > 1) {
if (vals.get(0) instanceof AnnotationMirror) {
isContainerDocumented = true;
return new SimpleAnnotationValueVisitor9<Boolean, Void>() {
@Override
public Boolean visitAnnotation(AnnotationMirror a, Void p) {
isContainerDocumented = true;
Element asElement = a.getAnnotationType().asElement();
if (utils.isDocumentedAnnotation((TypeElement)asElement)) {
isAnnotationDocumented = true;
}
return true;
}
@Override
protected Boolean defaultAction(Object o, Void p) {
return false;
}
}.visit(vals.get(0));
}
}
return false;
}
@Override
protected Boolean defaultAction(Object o, Void p) {
return false;
}
}.visit(annotationValue);
if (rvalue) {
return true;
}
}
return false;
}
private Content annotationValueToContent(AnnotationValue annotationValue) {
return new SimpleAnnotationValueVisitor9<Content, Void>() {
@Override
public Content visitType(TypeMirror t, Void p) {
return new SimpleTypeVisitor9<Content, Void>() {
@Override
public Content visitDeclared(DeclaredType t, Void p) {
LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.ANNOTATION, t);
String name = utils.isIncluded(t.asElement())
? t.asElement().getSimpleName().toString()
: utils.getFullyQualifiedName(t.asElement());
linkInfo.label = new StringContent(name + utils.getDimension(t) + ".class");
return getLink(linkInfo);
}
@Override
protected Content defaultAction(TypeMirror e, Void p) {
return new StringContent(t + utils.getDimension(t) + ".class");
}
}.visit(t);
}
@Override
public Content visitAnnotation(AnnotationMirror a, Void p) {
List<Content> list = getAnnotations(0, a, false);
ContentBuilder buf = new ContentBuilder();
for (Content c : list) {
buf.addContent(c);
}
return buf;
}
@Override
public Content visitEnumConstant(VariableElement c, Void p) {
return getDocLink(LinkInfoImpl.Kind.ANNOTATION,
c, c.getSimpleName(), false);
}
@Override
public Content visitArray(List<? extends AnnotationValue> vals, Void p) {
ContentBuilder buf = new ContentBuilder();
String sep = "";
for (AnnotationValue av : vals) {
buf.addContent(sep);
buf.addContent(visit(av));
sep = " ";
}
return buf;
}
@Override
protected Content defaultAction(Object o, Void p) {
return new StringContent(annotationValue.toString());
}
}.visit(annotationValue);
}
Return the configuration for this doclet.
Returns: the configuration for this doclet.
/**
* Return the configuration for this doclet.
*
* @return the configuration for this doclet.
*/
@Override
public Configuration configuration() {
return configuration;
}
}