blob: 79b588b7a0dae90f2f52bd79052cbcce2849236d [file] [log] [blame]
/*
* Copyright (c) 2018, 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.markup;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import jdk.javadoc.internal.doclets.formats.html.AbstractMemberWriter;
import jdk.javadoc.internal.doclets.formats.html.Contents;
import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration;
import jdk.javadoc.internal.doclets.formats.html.SectionName;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.builders.MemberSummaryBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
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.VisibleMemberTable;
import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind.*;
/**
* Factory for navigation bar.
*
* <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>
*/
public class Navigation {
private final HtmlConfiguration configuration;
private final Element element;
private final Contents contents;
private final DocPath path;
private final DocPath pathToRoot;
private final Links links;
private final HtmlTree fixedNavDiv;
private final PageMode documentedPage;
private Content navLinkModule;
private Content navLinkPackage;
private Content navLinkClass;
private MemberSummaryBuilder memberSummaryBuilder;
private boolean displaySummaryModuleDescLink;
private boolean displaySummaryModulesLink;
private boolean displaySummaryPackagesLink;
private boolean displaySummaryServicesLink;
private final Map<Position, Deque<Content>> topBottomNavContents;
private Content userHeader;
private Content userFooter;
private final String rowListTitle;
private final Content searchLabel;
private static final Script FIXED_NAV_SCRIPT = new Script("<!--\n"
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
+ "//-->\n");
public enum PageMode {
ALLCLASSES,
ALLPACKAGES,
CLASS,
CONSTANTVALUES,
DEPRECATED,
DOCFILE,
HELP,
INDEX,
MODULE,
OVERVIEW,
PACKAGE,
SERIALIZEDFORM,
TREE,
USE;
}
enum Position {
BOTTOM("allclasses_navbar_bottom", HtmlConstants.START_OF_BOTTOM_NAVBAR, HtmlConstants.END_OF_BOTTOM_NAVBAR),
TOP("allclasses_navbar_top", HtmlConstants.START_OF_TOP_NAVBAR, HtmlConstants.END_OF_TOP_NAVBAR);
final String allClassesLinkId;
final Content startOfNav;
final Content endOfNav;
Position(String allClassesLinkId, Content startOfNav, Content endOfNav) {
this.allClassesLinkId = allClassesLinkId;
this.startOfNav = startOfNav;
this.endOfNav = endOfNav;
}
String allClassesLinkId() {
return allClassesLinkId;
}
Content startOfNav() {
return startOfNav;
}
Content endOfNav() {
return endOfNav;
}
Script allClassesLinkScript() {
return new Script("<!--\n"
+ " allClassesLink = document.getElementById(")
.appendStringLiteral(allClassesLinkId)
.append(");\n"
+ " if(window==top) {\n"
+ " allClassesLink.style.display = \"block\";\n"
+ " }\n"
+ " else {\n"
+ " allClassesLink.style.display = \"none\";\n"
+ " }\n"
+ " //-->\n");
}
}
/**
* Creates a {@code Navigation} object for a specific file, to be written in a specific HTML
* version.
*
* @param element element being documented. null if its not an element documentation page
* @param configuration the configuration object
* @param fixedNavDiv the fixed navigation for the header navigation
* @param page the kind of page being documented
* @param path the DocPath object
*/
public Navigation(Element element, HtmlConfiguration configuration, HtmlTree fixedNavDiv,
PageMode page, DocPath path) {
this.configuration = configuration;
this.element = element;
this.fixedNavDiv = fixedNavDiv;
this.contents = configuration.contents;
this.documentedPage = page;
this.path = path;
this.pathToRoot = path.parent().invert();
this.links = new Links(path, configuration.htmlVersion);
this.topBottomNavContents = new HashMap<>();
this.rowListTitle = configuration.getText("doclet.Navigation");
this.searchLabel = configuration.getContent("doclet.search");
populateNavContents(Position.TOP);
populateNavContents(Position.BOTTOM);
}
/**
* Populate the navigation contents for top and bottom navigation
*
* @param position the position of the navigation bar on the page
*/
private void populateNavContents(Position position) {
Deque<Content> queue = new ArrayDeque<>();
Content skipNavLinks = configuration.getContent("doclet.Skip_navigation_links");
switch (position) {
case TOP:
queue.addLast(links.createAnchor(SectionName.NAVBAR_TOP));
queue.addLast(links.createLink(SectionName.SKIP_NAVBAR_TOP, skipNavLinks,
skipNavLinks.toString(), ""));
queue.addLast(links.createAnchor(SectionName.NAVBAR_TOP_FIRSTROW));
queue.addLast(links.createAnchor(SectionName.SKIP_NAVBAR_TOP));
topBottomNavContents.put(position, queue);
break;
case BOTTOM:
queue.addLast(links.createAnchor(SectionName.NAVBAR_BOTTOM));
queue.addLast(links.createLink(SectionName.SKIP_NAVBAR_BOTTOM, skipNavLinks,
skipNavLinks.toString(), ""));
queue.addLast(links.createAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW));
queue.addLast(links.createAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
topBottomNavContents.put(position, queue);
break;
default:
break;
}
}
public Navigation setNavLinkModule(Content navLinkModule) {
this.navLinkModule = navLinkModule;
return this;
}
public Navigation setNavLinkPackage(Content navLinkPackage) {
this.navLinkPackage = navLinkPackage;
return this;
}
public Navigation setNavLinkClass(Content navLinkClass) {
this.navLinkClass = navLinkClass;
return this;
}
public Navigation setMemberSummaryBuilder(MemberSummaryBuilder memberSummaryBuilder) {
this.memberSummaryBuilder = memberSummaryBuilder;
return this;
}
public Navigation setDisplaySummaryModuleDescLink(boolean displaySummaryModuleDescLink) {
this.displaySummaryModuleDescLink = displaySummaryModuleDescLink;
return this;
}
public Navigation setDisplaySummaryModulesLink(boolean displaySummaryModulesLink) {
this.displaySummaryModulesLink = displaySummaryModulesLink;
return this;
}
public Navigation setDisplaySummaryPackagesLink(boolean displaySummaryPackagesLink) {
this.displaySummaryPackagesLink = displaySummaryPackagesLink;
return this;
}
public Navigation setDisplaySummaryServicesLink(boolean displaySummaryServicesLink) {
this.displaySummaryServicesLink = displaySummaryServicesLink;
return this;
}
public Navigation setUserHeader(Content userHeader) {
this.userHeader = userHeader;
return this;
}
public Navigation setUserFooter(Content userFooter) {
this.userFooter = userFooter;
return this;
}
/**
* Add the links for the main navigation.
*
* @param tree the content tree to which the main navigation will added
*/
private void addMainNavLinks(Content tree) {
switch (documentedPage) {
case OVERVIEW:
addActivePageLink(tree, contents.overviewLabel, configuration.createoverview);
addModuleLink(tree);
addPackageLink(tree);
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addTreeLink(tree);
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case MODULE:
addOverviewLink(tree);
addActivePageLink(tree, contents.moduleLabel, configuration.showModules);
addPackageLink(tree);
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addTreeLink(tree);
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case PACKAGE:
addOverviewLink(tree);
addModuleOfElementLink(tree);
addActivePageLink(tree, contents.packageLabel, true);
addPageLabel(tree, contents.classLabel, true);
if (configuration.classuse) {
addContentToTree(tree, links.createLink(DocPaths.PACKAGE_USE,
contents.useLabel, "", ""));
}
if (configuration.createtree) {
addContentToTree(tree, links.createLink(DocPaths.PACKAGE_TREE,
contents.treeLabel, "", ""));
}
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case CLASS:
addOverviewLink(tree);
addModuleOfElementLink(tree);
addPackageSummaryLink(tree);
addActivePageLink(tree, contents.classLabel, true);
if (configuration.classuse) {
addContentToTree(tree, links.createLink(DocPaths.CLASS_USE.resolve(path.basename()),
contents.useLabel));
}
if (configuration.createtree) {
addContentToTree(tree, links.createLink(DocPaths.PACKAGE_TREE,
contents.treeLabel, "", ""));
}
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case USE:
addOverviewLink(tree);
addModuleOfElementLink(tree);
if (element instanceof PackageElement) {
addPackageSummaryLink(tree);
addPageLabel(tree, contents.classLabel, true);
} else {
addPackageOfElementLink(tree);
addContentToTree(tree, navLinkClass);
}
addActivePageLink(tree, contents.useLabel, configuration.classuse);
if (element instanceof PackageElement) {
addContentToTree(tree, links.createLink(DocPaths.PACKAGE_TREE, contents.treeLabel));
} else {
addContentToTree(tree, configuration.utils.isEnclosingPackageIncluded((TypeElement) element)
? links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel)
: links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel));
}
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case TREE:
addOverviewLink(tree);
if (element == null) {
addPageLabel(tree, contents.moduleLabel, configuration.showModules);
addPageLabel(tree, contents.packageLabel, true);
} else {
addModuleOfElementLink(tree);
addPackageSummaryLink(tree);
}
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addActivePageLink(tree, contents.treeLabel, configuration.createtree);
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case DEPRECATED:
case INDEX:
case HELP:
addOverviewLink(tree);
addModuleLink(tree);
addPackageLink(tree);
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addTreeLink(tree);
if (documentedPage == PageMode.DEPRECATED) {
addActivePageLink(tree, contents.deprecatedLabel, !(configuration.nodeprecated
|| configuration.nodeprecatedlist));
} else {
addDeprecatedLink(tree);
}
if (documentedPage == PageMode.INDEX) {
addActivePageLink(tree, contents.indexLabel, configuration.createindex);
} else {
addIndexLink(tree);
}
if (documentedPage == PageMode.HELP) {
addActivePageLink(tree, contents.helpLabel, !configuration.nohelp);
} else {
addHelpLink(tree);
}
break;
case ALLCLASSES:
case ALLPACKAGES:
case CONSTANTVALUES:
case SERIALIZEDFORM:
addOverviewLink(tree);
addModuleLink(tree);
addPackageLink(tree);
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addTreeLink(tree);
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
case DOCFILE:
addOverviewLink(tree);
addModuleOfElementLink(tree);
addContentToTree(tree, navLinkPackage);
addPageLabel(tree, contents.classLabel, true);
addPageLabel(tree, contents.useLabel, configuration.classuse);
addTreeLink(tree);
addDeprecatedLink(tree);
addIndexLink(tree);
addHelpLink(tree);
break;
default:
break;
}
}
/**
* Add the summary links to the sub-navigation.
*
* @param tree the content tree to which the sub-navigation will added
*/
private void addSummaryLinks(Content tree) {
List<Content> listContents = new ArrayList<>();
switch (documentedPage) {
case CLASS:
if (element.getKind() == ElementKind.ANNOTATION_TYPE) {
addAnnotationTypeSummaryLink("doclet.navField",
ANNOTATION_TYPE_FIELDS, listContents);
addAnnotationTypeSummaryLink("doclet.navAnnotationTypeRequiredMember",
ANNOTATION_TYPE_MEMBER_REQUIRED, listContents);
addAnnotationTypeSummaryLink("doclet.navAnnotationTypeOptionalMember",
ANNOTATION_TYPE_MEMBER_OPTIONAL, listContents);
} else {
TypeElement typeElement = (TypeElement) element;
for (VisibleMemberTable.Kind kind : summarySet) {
if (kind == ENUM_CONSTANTS && !configuration.utils.isEnum(typeElement)) {
continue;
}
if (kind == CONSTRUCTORS && configuration.utils.isEnum(typeElement)) {
continue;
}
AbstractMemberWriter writer
= ((AbstractMemberWriter) memberSummaryBuilder.getMemberSummaryWriter(kind));
if (writer == null) {
addContentToList(listContents, contents.getNavLinkLabelContent(kind));
} else {
addTypeSummaryLink(memberSummaryBuilder.members(kind),
memberSummaryBuilder.getVisibleMemberTable(),
kind, listContents);
}
}
}
if (!listContents.isEmpty()) {
Content li = HtmlTree.LI(contents.summaryLabel);
li.addContent(Contents.SPACE);
tree.addContent(li);
addListToNav(listContents, tree);
}
break;
case MODULE:
if (displaySummaryModuleDescLink) {
addContentToList(listContents,
links.createLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription));
} else {
addContentToList(listContents, contents.navModuleDescription);
}
if (displaySummaryModulesLink) {
addContentToList(listContents,
links.createLink(SectionName.MODULES, contents.navModules));
} else {
addContentToList(listContents, contents.navModules);
}
if (displaySummaryPackagesLink) {
addContentToList(listContents,
links.createLink(SectionName.PACKAGES, contents.navPackages));
} else {
addContentToList(listContents, contents.navPackages);
}
if (displaySummaryServicesLink) {
addContentToList(listContents,
links.createLink(SectionName.SERVICES, contents.navServices));
} else {
addContentToList(listContents, contents.navServices);
}
if (!listContents.isEmpty()) {
Content li = HtmlTree.LI(contents.moduleSubNavLabel);
li.addContent(Contents.SPACE);
tree.addContent(li);
addListToNav(listContents, tree);
}
break;
default:
break;
}
}
/**
* Add the navigation summary link.
*
* @param members members to be linked
* @param vmt the visible member table
* @param kind the visible member kind
* @param listContents the list of contents
*/
private void addTypeSummaryLink(SortedSet<? extends Element> members,
VisibleMemberTable vmt,
VisibleMemberTable.Kind kind, List<Content> listContents) {
if (!members.isEmpty()) {
addTypeSummaryLink(null, kind, true, listContents);
return;
}
Set<TypeElement> visibleClasses = vmt.getVisibleTypeElements();
for (TypeElement t : visibleClasses) {
if (configuration.getVisibleMemberTable(t).hasVisibleMembers(kind)) {
addTypeSummaryLink(null, kind, true, listContents);
return;
}
}
addTypeSummaryLink(null, kind, false, listContents);
}
/**
* Add the navigation Type summary link.
*
* @param typeElement the Type being documented
* @param kind the kind of member being documented
* @param link true if the members are listed and need to be linked
* @param listContents the list of contents to which the summary will be added
*/
private void addTypeSummaryLink(TypeElement typeElement, VisibleMemberTable.Kind kind, boolean link,
List<Content> listContents) {
switch (kind) {
case CONSTRUCTORS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.CONSTRUCTOR_SUMMARY,
contents.navConstructor));
} else {
addContentToList(listContents, contents.navConstructor);
}
break;
case ENUM_CONSTANTS:
if (link) {
if (typeElement == null) {
addContentToList(listContents, links.createLink(SectionName.ENUM_CONSTANT_SUMMARY,
contents.navEnum));
} else {
addContentToList(listContents, links.createLink(
SectionName.ENUM_CONSTANTS_INHERITANCE,
configuration.getClassName(typeElement), contents.navEnum));
}
} else {
addContentToList(listContents, contents.navEnum);
}
break;
case FIELDS:
if (link) {
if (typeElement == null) {
addContentToList(listContents,
links.createLink(SectionName.FIELD_SUMMARY, contents.navField));
} else {
addContentToList(listContents, links.createLink(SectionName.FIELDS_INHERITANCE,
configuration.getClassName(typeElement), contents.navField));
}
} else {
addContentToList(listContents, contents.navField);
}
break;
case METHODS:
if (link) {
if (typeElement == null) {
addContentToList(listContents,
links.createLink(SectionName.METHOD_SUMMARY, contents.navMethod));
} else {
addContentToList(listContents, links.createLink(SectionName.METHODS_INHERITANCE,
configuration.getClassName(typeElement), contents.navMethod));
}
} else {
addContentToList(listContents, contents.navMethod);
}
break;
case INNER_CLASSES:
if (link) {
if (typeElement == null) {
addContentToList(listContents,
links.createLink(SectionName.NESTED_CLASS_SUMMARY, contents.navNested));
} else {
addContentToList(listContents, links.createLink(SectionName.NESTED_CLASSES_INHERITANCE,
configuration.utils.getFullyQualifiedName(typeElement), contents.navNested));
}
} else {
addContentToList(listContents, contents.navNested);
}
break;
case PROPERTIES:
if (link) {
if (typeElement == null) {
addContentToList(listContents,
links.createLink(SectionName.PROPERTY_SUMMARY, contents.navProperty));
} else {
addContentToList(listContents, links.createLink(SectionName.PROPERTIES_INHERITANCE,
configuration.getClassName(typeElement), contents.navProperty));
}
} else {
addContentToList(listContents, contents.navProperty);
}
break;
default:
break;
}
}
/**
* Add the navigation Type summary link.
*
* @param label the label to be added
* @param kind the kind of member being documented
* @param listContents the list of contents to which the summary will be added
*/
private void addAnnotationTypeSummaryLink(String label, VisibleMemberTable.Kind kind, List<Content> listContents) {
AbstractMemberWriter writer = ((AbstractMemberWriter) memberSummaryBuilder.
getMemberSummaryWriter(kind));
if (writer == null) {
addContentToList(listContents, contents.getContent(label));
} else {
boolean link = memberSummaryBuilder.getVisibleMemberTable().hasVisibleMembers(kind);
switch (kind) {
case ANNOTATION_TYPE_FIELDS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.ANNOTATION_TYPE_FIELD_SUMMARY,
contents.navField));
} else {
addContentToList(listContents, contents.navField);
}
break;
case ANNOTATION_TYPE_MEMBER_REQUIRED:
if (link) {
addContentToList(listContents, links.createLink(
SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY,
contents.navAnnotationTypeRequiredMember));
} else {
addContentToList(listContents, contents.navAnnotationTypeRequiredMember);
}
break;
case ANNOTATION_TYPE_MEMBER_OPTIONAL:
if (link) {
addContentToList(listContents, links.createLink(
SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY,
contents.navAnnotationTypeOptionalMember));
} else {
addContentToList(listContents, contents.navAnnotationTypeOptionalMember);
}
break;
default:
break;
}
}
}
/**
* Add the detail links to sub-navigation.
*
* @param tree the content tree to which the links will be added
*/
private void addDetailLinks(Content tree) {
switch (documentedPage) {
case CLASS:
List<Content> listContents = new ArrayList<>();
if (element.getKind() == ElementKind.ANNOTATION_TYPE) {
addAnnotationTypeDetailLink(listContents);
} else {
TypeElement typeElement = (TypeElement) element;
for (VisibleMemberTable.Kind kind : detailSet) {
AbstractMemberWriter writer
= ((AbstractMemberWriter) memberSummaryBuilder.
getMemberSummaryWriter(kind));
if (kind == ENUM_CONSTANTS && !configuration.utils.isEnum(typeElement)) {
continue;
}
if (kind == CONSTRUCTORS && configuration.utils.isEnum(typeElement)) {
continue;
}
if (writer == null) {
addContentToList(listContents, contents.getNavLinkLabelContent(kind));
} else {
addTypeDetailLink(kind, memberSummaryBuilder.hasMembers(kind), listContents);
}
}
}
if (!listContents.isEmpty()) {
Content li = HtmlTree.LI(contents.detailLabel);
li.addContent(Contents.SPACE);
tree.addContent(li);
addListToNav(listContents, tree);
}
break;
default:
break;
}
}
/**
* Add the navigation Type detail link.
*
* @param kind the kind of member being documented
* @param link true if the members are listed and need to be linked
* @param listContents the list of contents to which the detail will be added.
*/
protected void addTypeDetailLink(VisibleMemberTable.Kind kind, boolean link, List<Content> listContents) {
switch (kind) {
case CONSTRUCTORS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.CONSTRUCTOR_DETAIL, contents.navConstructor));
} else {
addContentToList(listContents, contents.navConstructor);
}
break;
case ENUM_CONSTANTS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.ENUM_CONSTANT_DETAIL, contents.navEnum));
} else {
addContentToList(listContents, contents.navEnum);
}
break;
case FIELDS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.FIELD_DETAIL, contents.navField));
} else {
addContentToList(listContents, contents.navField);
}
break;
case METHODS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.METHOD_DETAIL, contents.navMethod));
} else {
addContentToList(listContents, contents.navMethod);
}
break;
case PROPERTIES:
if (link) {
addContentToList(listContents, links.createLink(SectionName.PROPERTY_DETAIL, contents.navProperty));
} else {
addContentToList(listContents, contents.navProperty);
}
break;
default:
break;
}
}
/**
* Add the navigation Annotation Type detail link.
*
* @param listContents the list of contents to which the annotation detail will be added.
*/
protected void addAnnotationTypeDetailLink(List<Content> listContents) {
TypeElement annotationType = (TypeElement) element;
AbstractMemberWriter writerField
= ((AbstractMemberWriter) memberSummaryBuilder.
getMemberSummaryWriter(ANNOTATION_TYPE_FIELDS));
AbstractMemberWriter writerOptional
= ((AbstractMemberWriter) memberSummaryBuilder.
getMemberSummaryWriter(ANNOTATION_TYPE_MEMBER_OPTIONAL));
AbstractMemberWriter writerRequired
= ((AbstractMemberWriter) memberSummaryBuilder.
getMemberSummaryWriter(ANNOTATION_TYPE_MEMBER_REQUIRED));
if (writerField != null) {
addAnnotationTypeDetailLink(ANNOTATION_TYPE_FIELDS,
!configuration.utils.getAnnotationFields(annotationType).isEmpty(),
listContents);
} else {
addContentToList(listContents, contents.navField);
}
if (writerOptional != null) {
addAnnotationTypeDetailLink(ANNOTATION_TYPE_MEMBER_OPTIONAL,
!annotationType.getAnnotationMirrors().isEmpty(), listContents);
} else if (writerRequired != null) {
addAnnotationTypeDetailLink(ANNOTATION_TYPE_MEMBER_REQUIRED,
!annotationType.getAnnotationMirrors().isEmpty(), listContents);
} else {
addContentToList(listContents, contents.navAnnotationTypeMember);
}
}
/**
* Add the navigation Annotation Type detail link.
*
* @param type the kind of member being documented
* @param link true if the member details need to be linked
* @param listContents the list of contents to which the annotation detail will be added.
*/
protected void addAnnotationTypeDetailLink(VisibleMemberTable.Kind type, boolean link, List<Content> listContents) {
switch (type) {
case ANNOTATION_TYPE_FIELDS:
if (link) {
addContentToList(listContents, links.createLink(SectionName.ANNOTATION_TYPE_FIELD_DETAIL,
contents.navField));
} else {
addContentToList(listContents, contents.navField);
}
break;
case ANNOTATION_TYPE_MEMBER_REQUIRED:
case ANNOTATION_TYPE_MEMBER_OPTIONAL:
if (link) {
addContentToList(listContents, links.createLink(SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL,
contents.navAnnotationTypeMember));
} else {
addContentToList(listContents, contents.navAnnotationTypeMember);
}
break;
default:
break;
}
}
private void addContentToList(List<Content> listContents, Content tree) {
listContents.add(HtmlTree.LI(tree));
}
private void addContentToTree(Content tree, Content content) {
tree.addContent(HtmlTree.LI(content));
}
private void addListToNav(List<Content> listContents, Content tree) {
int count = 0;
for (Content liContent : listContents) {
if (count < listContents.size() - 1) {
liContent.addContent(Contents.SPACE);
liContent.addContent("|");
liContent.addContent(Contents.SPACE);
}
tree.addContent(liContent);
count++;
}
}
private void addActivePageLink(Content tree, Content label, boolean display) {
if (display) {
tree.addContent(HtmlTree.LI(HtmlStyle.navBarCell1Rev, label));
}
}
private void addPageLabel(Content tree, Content label, boolean display) {
if (display) {
tree.addContent(HtmlTree.LI(label));
}
}
private void addOverviewLink(Content tree) {
if (configuration.createoverview) {
tree.addContent(HtmlTree.LI(links.createLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
contents.overviewLabel, "", "")));
}
}
private void addModuleLink(Content tree) {
if (configuration.showModules) {
if (configuration.modules.size() == 1) {
ModuleElement mdle = configuration.modules.first();
boolean included = configuration.utils.isIncluded(mdle);
tree.addContent(HtmlTree.LI((included)
? links.createLink(pathToRoot.resolve(configuration.docPaths.moduleSummary(mdle)), contents.moduleLabel, "", "")
: contents.moduleLabel));
} else if (!configuration.modules.isEmpty()) {
addPageLabel(tree, contents.moduleLabel, true);
}
}
}
private void addModuleOfElementLink(Content tree) {
if (configuration.showModules) {
tree.addContent(HtmlTree.LI(navLinkModule));
}
}
private void addPackageLink(Content tree) {
if (configuration.packages.size() == 1) {
PackageElement packageElement = configuration.packages.first();
boolean included = packageElement != null && configuration.utils.isIncluded(packageElement);
if (!included) {
for (PackageElement p : configuration.packages) {
if (p.equals(packageElement)) {
included = true;
break;
}
}
}
if (included || packageElement == null) {
tree.addContent(HtmlTree.LI(links.createLink(
pathToRoot.resolve(configuration.docPaths.forPackage(packageElement).resolve(DocPaths.PACKAGE_SUMMARY)),
contents.packageLabel)));
} else {
DocLink crossPkgLink = configuration.extern.getExternalLink(
packageElement, pathToRoot, DocPaths.PACKAGE_SUMMARY.getPath());
if (crossPkgLink != null) {
tree.addContent(HtmlTree.LI(links.createLink(crossPkgLink, contents.packageLabel)));
} else {
tree.addContent(HtmlTree.LI(contents.packageLabel));
}
}
} else if (!configuration.packages.isEmpty()) {
addPageLabel(tree, contents.packageLabel, true);
}
}
private void addPackageOfElementLink(Content tree) {
tree.addContent(HtmlTree.LI(links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY),
contents.packageLabel)));
}
private void addPackageSummaryLink(Content tree) {
tree.addContent(HtmlTree.LI(links.createLink(DocPaths.PACKAGE_SUMMARY, contents.packageLabel)));
}
private void addTreeLink(Content tree) {
if (configuration.createtree) {
List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackageElements());
DocPath docPath = packages.size() == 1 && configuration.getSpecifiedTypeElements().isEmpty()
? pathToRoot.resolve(configuration.docPaths.forPackage(packages.get(0)).resolve(DocPaths.PACKAGE_TREE))
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
tree.addContent(HtmlTree.LI(links.createLink(docPath, contents.treeLabel, "", "")));
}
}
private void addDeprecatedLink(Content tree) {
if (!(configuration.nodeprecated || configuration.nodeprecatedlist)) {
tree.addContent(HtmlTree.LI(links.createLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
contents.deprecatedLabel, "", "")));
}
}
private void addIndexLink(Content tree) {
if (configuration.createindex) {
tree.addContent(HtmlTree.LI(links.createLink(pathToRoot.resolve(
(configuration.splitindex
? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
: DocPaths.INDEX_ALL)),
contents.indexLabel, "", "")));
}
}
private void addHelpLink(Content tree) {
if (!configuration.nohelp) {
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());
}
tree.addContent(HtmlTree.LI(links.createLink(pathToRoot.resolve(helpfilenm),
contents.helpLabel, "", "")));
}
}
/**
* Add "FRAMES" link, to switch to the frame version of the output.
*
* @param tree the content tree to which the link will be added
*/
private void addNavShowLists(Content tree) {
DocLink dl = new DocLink(pathToRoot.resolve(DocPaths.INDEX), path.getPath(), null);
Content framesContent = links.createLink(dl, contents.framesLabel, "", "_top");
tree.addContent(HtmlTree.LI(framesContent));
}
/**
* Add "NO FRAMES" link, to switch to the non-frame version of the output.
*
* @param tree the content tree to which the link will be added
*/
private void addNavHideLists(Content tree) {
Content noFramesContent = links.createLink(path.basename(), contents.noFramesLabel, "", "_top");
tree.addContent(HtmlTree.LI(noFramesContent));
}
private void addNavLinkClassIndex(Content tree) {
Content allClassesContent = links.createLink(pathToRoot.resolve(
DocPaths.AllClasses(configuration.frames)),
contents.allClassesLabel, "", "");
tree.addContent(HtmlTree.LI(allClassesContent));
}
private void addSearch(Content tree) {
String searchValueId = "search";
String reset = "reset";
HtmlTree inputText = HtmlTree.INPUT("text", searchValueId, searchValueId);
HtmlTree inputReset = HtmlTree.INPUT(reset, reset, reset);
HtmlTree liInput = HtmlTree.LI(HtmlTree.LABEL(searchValueId, searchLabel));
liInput.addContent(inputText);
liInput.addContent(inputReset);
HtmlTree ulSearch = HtmlTree.UL(HtmlStyle.navListSearch, liInput);
tree.addContent(ulSearch);
}
private void addAllClassesLinkScript(Content tree, boolean top) {
Content div = HtmlTree.DIV(top
? Position.TOP.allClassesLinkScript().asContent()
: Position.BOTTOM.allClassesLinkScript().asContent());
Content div_noscript = HtmlTree.DIV(contents.noScriptMessage);
Content noScript = HtmlTree.NOSCRIPT(div_noscript);
div.addContent(noScript);
tree.addContent(div);
}
private void addFixedNavScript(Content tree) {
tree.addContent(FIXED_NAV_SCRIPT.asContent());
}
/**
* Get the navigation content.
*
* @param top true if the top navigation bar is to be printed
* @return the navigation contents
*/
public Content getContent(boolean top) {
Content contentTree = new ContentBuilder();
if (!configuration.nonavbar) {
Deque<Content> queue;
Content tree = (configuration.htmlVersion == HtmlVersion.HTML5)
? HtmlTree.NAV()
: contentTree;
HtmlTree navDiv = new HtmlTree(HtmlTag.DIV);
if (top) {
queue = topBottomNavContents.get(Position.TOP);
fixedNavDiv.addContent(Position.TOP.startOfNav());
navDiv.setStyle(HtmlStyle.topNav);
} else {
queue = topBottomNavContents.get(Position.BOTTOM);
tree.addContent(Position.BOTTOM.startOfNav());
navDiv.setStyle(HtmlStyle.bottomNav);
}
navDiv.addContent(queue.poll());
HtmlTree skipLinkDiv = HtmlTree.DIV(HtmlStyle.skipNav, queue.poll());
navDiv.addContent(skipLinkDiv);
navDiv.addContent(queue.poll());
HtmlTree navList = new HtmlTree(HtmlTag.UL);
navList.setStyle(HtmlStyle.navList);
navList.addAttr(HtmlAttr.TITLE, rowListTitle);
fixedNavDiv.setStyle(HtmlStyle.fixedNav);
addMainNavLinks(navList);
navDiv.addContent(navList);
Content aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, top ? userHeader : userFooter);
navDiv.addContent(aboutDiv);
if (top) {
fixedNavDiv.addContent(navDiv);
} else {
tree.addContent(navDiv);
}
HtmlTree subDiv = new HtmlTree(HtmlTag.DIV);
subDiv.setStyle(HtmlStyle.subNav);
HtmlTree ulFrames = new HtmlTree(HtmlTag.UL);
ulFrames.setStyle(HtmlStyle.navList);
if (!configuration.nonavbar) {
if (configuration.frames) {
addNavShowLists(ulFrames);
addNavHideLists(ulFrames);
}
}
subDiv.addContent(ulFrames);
HtmlTree ulAllClasses = new HtmlTree(HtmlTag.UL);
ulAllClasses.setStyle(HtmlStyle.navList);
ulAllClasses.addAttr(HtmlAttr.ID, top
? Position.TOP.allClassesLinkId()
: Position.BOTTOM.allClassesLinkId());
addNavLinkClassIndex(ulAllClasses);
subDiv.addContent(ulAllClasses);
if (top && configuration.createindex) {
addSearch(subDiv);
}
addAllClassesLinkScript(subDiv, top);
HtmlTree div = new HtmlTree(HtmlTag.DIV);
// Add the summary links if present.
HtmlTree ulNavSummary = new HtmlTree(HtmlTag.UL);
ulNavSummary.setStyle(HtmlStyle.subNavList);
addSummaryLinks(ulNavSummary);
div.addContent(ulNavSummary);
// Add the detail links if present.
HtmlTree ulNavDetail = new HtmlTree(HtmlTag.UL);
ulNavDetail.setStyle(HtmlStyle.subNavList);
addDetailLinks(ulNavDetail);
div.addContent(ulNavDetail);
subDiv.addContent(div);
subDiv.addContent(queue.poll());
if (top) {
fixedNavDiv.addContent(subDiv);
fixedNavDiv.addContent(Position.TOP.endOfNav());
tree.addContent(fixedNavDiv);
HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
tree.addContent(paddingDiv);
addFixedNavScript(tree);
} else {
tree.addContent(subDiv);
tree.addContent(Position.BOTTOM.endOfNav());
}
return tree;
}
return contentTree;
}
}