--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Fri Dec 16 18:54:09 2016 +0300
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Fri Dec 16 09:07:57 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 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
@@ -25,17 +25,24 @@
package jdk.javadoc.internal.doclets.formats.html;
-import java.util.ArrayList;
-import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.ModuleElement.DirectiveKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
import com.sun.source.doctree.DocTree;
+import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
+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.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@@ -47,12 +54,12 @@
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
+import jdk.javadoc.internal.doclets.toolkit.util.ModulePackageTypes;
/**
- * Class to generate file for each module contents in the right-hand
- * frame. This will list all the packages and Class Kinds in the module. A click on any
- * class-kind will update the frame with the clicked class-kind page. A click on any
- * package will update the frame with the clicked module package page.
+ * Class to generate file for each module contents in the right-hand frame. This will list all the
+ * required modules, packages and service types for the module. A click on any of the links will update
+ * the frame with the clicked element page.
*
* <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.
@@ -78,8 +85,82 @@
*/
protected ModuleElement mdle;
- private final Map<ModuleElement.DirectiveKind, List<ModuleElement.Directive>> directiveMap
- = new EnumMap<>(ModuleElement.DirectiveKind.class);
+ /**
+ * The module mode for this javadoc run. It can be set to "api" or "all".
+ */
+ private final ModuleMode moduleMode;
+
+ /**
+ * Map of module elements and modifiers required by this module.
+ */
+ private final Map<ModuleElement, Content> requires
+ = new TreeMap<>(utils.makeModuleComparator());
+
+ /**
+ * Map of additional modules and modifiers, transitive closure, required by this module.
+ */
+ private final Map<ModuleElement, Content> additionalModules
+ = new TreeMap<>(utils.makeModuleComparator());
+
+ /**
+ * Map of packages exported by this module and the modules it's been exported to.
+ */
+ private final Map<PackageElement, SortedSet<ModuleElement>> exportedPackages
+ = new TreeMap<>(utils.makePackageComparator());
+
+ /**
+ * Map of opened packages by this module and the modules it's been opened to.
+ */
+ private final Map<PackageElement, SortedSet<ModuleElement>> openedPackages
+ = new TreeMap<>(utils.makePackageComparator());
+
+ /**
+ * Set of concealed packages of this module.
+ */
+ private final SortedSet<PackageElement> concealedPackages = new TreeSet<>(utils.makePackageComparator());
+
+ /**
+ * Map of additional modules (transitive closure) and its exported packages.
+ */
+ private final Map<ModuleElement, SortedSet<PackageElement>> additionalPackages
+ = new TreeMap<>(utils.makeModuleComparator());
+
+ /**
+ * Map of additional modules (transitive closure) and its open packages.
+ */
+ private final Map<ModuleElement, SortedSet<PackageElement>> additionalOpenPackages
+ = new TreeMap<>(utils.makeModuleComparator());
+
+ /**
+ * Set of services used by the module.
+ */
+ private final SortedSet<TypeElement> uses
+ = new TreeSet<>(utils.makeAllClassesComparator());
+
+ /**
+ * Map of services used by the module and specified using @uses javadoc tag, and description.
+ */
+ private final Map<TypeElement, Content> usesTrees
+ = new TreeMap<>(utils.makeAllClassesComparator());
+
+ /**
+ * Map of services provided by this module, and set of its implementations.
+ */
+ private final Map<TypeElement, SortedSet<TypeElement>> provides
+ = new TreeMap<>(utils.makeAllClassesComparator());
+
+ /**
+ * Map of services provided by the module and specified using @provides javadoc tag, and
+ * description.
+ */
+ private final Map<TypeElement, Content> providesTrees
+ = new TreeMap<>(utils.makeAllClassesComparator());
+
+ private int packageTypesOr = 0;
+
+ protected Set<ModulePackageTypes> modulePackageTypes = EnumSet.noneOf(ModulePackageTypes.class);
+
+ protected Map<String, Integer> typeMap = new LinkedHashMap<>();
/**
* The HTML tree for main tag.
@@ -92,8 +173,7 @@
protected HtmlTree sectionTree = HtmlTree.SECTION();
/**
- * Constructor to construct ModuleWriter object and to generate
- * "moduleName-summary.html" file.
+ * Constructor to construct ModuleWriter object and to generate "moduleName-summary.html" file.
*
* @param configuration the configuration of the doclet.
* @param mdle Module under consideration.
@@ -106,7 +186,8 @@
this.prevModule = prevModule;
this.nextModule = nextModule;
this.mdle = mdle;
- generateDirectiveMap();
+ this.moduleMode = configuration.docEnv.getModuleMode();
+ computeModulesData();
}
/**
@@ -176,20 +257,165 @@
}
/**
- * Generate the directive map for the directives on the module.
+ * Compute the modules data that will be displayed in various tables on the module summary page.
*/
- public void generateDirectiveMap() {
- for (ModuleElement.Directive d : mdle.getDirectives()) {
- if (directiveMap.containsKey(d.getKind())) {
- List<ModuleElement.Directive> dir = directiveMap.get(d.getKind());
- dir.add(d);
- directiveMap.put(d.getKind(), dir);
+ public void computeModulesData() {
+ CommentHelper ch = utils.getCommentHelper(mdle);
+ // Get module dependencies using the module's transitive closure.
+ Map<ModuleElement, String> dependentModules = utils.getDependentModules(mdle);
+ // Add all dependent modules to additional modules set. We will remove the modules,
+ // listed using the requires directive, from this set to come up with the table of additional
+ // required modules.
+ dependentModules.forEach((module, mod) -> {
+ if (shouldDocument(module)) {
+ additionalModules.put(module, new StringContent(mod));
+ }
+ });
+ (ElementFilter.requiresIn(mdle.getDirectives())).forEach((directive) -> {
+ ModuleElement m = directive.getDependency();
+ if (shouldDocument(m)) {
+ if (moduleMode == ModuleMode.ALL || directive.isTransitive()) {
+ requires.put(m, new StringContent(utils.getModifiers(directive)));
} else {
- List<ModuleElement.Directive> dir = new ArrayList<>();
- dir.add(d);
- directiveMap.put(d.getKind(), dir);
+ // For api mode, just keep the public requires in dependentModules for display of
+ // additional packages in the "Packages" section.
+ dependentModules.remove(m);
+ }
+ additionalModules.remove(m);
+ }
+ });
+ // Get all packages for the module and put it in the concealed packages set.
+ (utils.getModulePackageMap().get(mdle)).forEach((pkg) -> {
+ if (shouldDocument(pkg)) {
+ concealedPackages.add(pkg);
+ }
+ });
+ // Get all exported packages for the module using the exports directive for the module.
+ (ElementFilter.exportsIn(mdle.getDirectives())).forEach((directive) -> {
+ PackageElement p = directive.getPackage();
+ if (shouldDocument(p)) {
+ SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
+ List<? extends ModuleElement> targetMdles = directive.getTargetModules();
+ if (targetMdles != null) {
+ mdleList.addAll(targetMdles);
+ }
+ // Qualified exports should not be displayed in the api mode. So if mdleList is empty,
+ // its exported to all modules and hence can be added.
+ if (moduleMode == ModuleMode.ALL || mdleList.isEmpty()) {
+ exportedPackages.put(p, mdleList);
+ }
+ concealedPackages.remove(p);
+ }
+ });
+ // Get all opened packages for the module using the opens directive for the module.
+ (ElementFilter.opensIn(mdle.getDirectives())).forEach((directive) -> {
+ PackageElement p = directive.getPackage();
+ if (shouldDocument(p)) {
+ SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
+ List<? extends ModuleElement> targetMdles = directive.getTargetModules();
+ if (targetMdles != null) {
+ mdleList.addAll(targetMdles);
+ }
+ // Qualified opens should not be displayed in the api mode. So if mdleList is empty,
+ // it's opened to all modules and hence can be added.
+ if (moduleMode == ModuleMode.ALL || mdleList.isEmpty()) {
+ openedPackages.put(p, mdleList);
+ }
+ concealedPackages.remove(p);
+ }
+ });
+ // Remove all the exported and opened packages so we have just the concealed packages now.
+ concealedPackages.removeAll(exportedPackages.keySet());
+ concealedPackages.removeAll(openedPackages.keySet());
+ // Get all the exported and opened packages, for the transitive closure of the module, to be displayed in
+ // the additional packages tables.
+ dependentModules.forEach((module, mod) -> {
+ SortedSet<PackageElement> pkgList = new TreeSet<>(utils.makePackageComparator());
+ (ElementFilter.exportsIn(module.getDirectives())).forEach((directive) -> {
+ PackageElement pkg = directive.getPackage();
+ if (shouldDocument(pkg)) {
+ pkgList.add(pkg);
+ }
+ });
+ // If none of the transitive modules have exported packages to be displayed, we should not be
+ // displaying the table and so it should not be added to the map.
+ if (!pkgList.isEmpty()) {
+ additionalPackages.put(module, pkgList);
}
- }
+ SortedSet<PackageElement> openPkgList = new TreeSet<>(utils.makePackageComparator());
+ (ElementFilter.opensIn(module.getDirectives())).forEach((directive) -> {
+ PackageElement pkg = directive.getPackage();
+ if (shouldDocument(pkg)) {
+ openPkgList.add(pkg);
+ }
+ });
+ // If none of the transitive modules have opened packages to be displayed, we should not be
+ // displaying the table and so it should not be added to the map.
+ if (!openPkgList.isEmpty()) {
+ additionalOpenPackages.put(module, openPkgList);
+ }
+ });
+ // Get all the services listed as uses directive.
+ (ElementFilter.usesIn(mdle.getDirectives())).forEach((directive) -> {
+ TypeElement u = directive.getService();
+ if (shouldDocument(u)) {
+ uses.add(u);
+ }
+ });
+ // Get all the services and implementations listed as provides directive.
+ (ElementFilter.providesIn(mdle.getDirectives())).forEach((directive) -> {
+ TypeElement u = directive.getService();
+ if (shouldDocument(u)) {
+ List<? extends TypeElement> implList = directive.getImplementations();
+ SortedSet<TypeElement> implSet = new TreeSet<>(utils.makeAllClassesComparator());
+ implSet.addAll(implList);
+ provides.put(u, implSet);
+ }
+ });
+ // Generate the map of all services listed using @provides, and the description.
+ (utils.getBlockTags(mdle, DocTree.Kind.PROVIDES)).forEach((tree) -> {
+ TypeElement t = ch.getServiceType(configuration, tree);
+ if (t != null) {
+ providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false));
+ }
+ });
+ // Generate the map of all services listed using @uses, and the description.
+ (utils.getBlockTags(mdle, DocTree.Kind.USES)).forEach((tree) -> {
+ TypeElement t = ch.getServiceType(configuration, tree);
+ if (t != null) {
+ usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false));
+ }
+ });
+ }
+
+ /**
+ * Returns true if the element should be documented on the module summary page.
+ *
+ * @param element the element to be checked
+ * @return true if the element should be documented
+ */
+ public boolean shouldDocument(Element element) {
+ return (moduleMode == ModuleMode.ALL || utils.isIncluded(element));
+ }
+
+ /**
+ * Returns true if there are elements to be displayed.
+ *
+ * @param section set of elements
+ * @return true if there are elements to be displayed
+ */
+ public boolean display(SortedSet<? extends Element> section) {
+ return section != null && !section.isEmpty();
+ }
+
+ /**
+ * Returns true if there are elements to be displayed.
+ *
+ * @param section map of elements.
+ * @return true if there are elements to be displayed
+ */
+ public boolean display(Map<? extends Element, ?> section) {
+ return section != null && !section.isEmpty();
}
/**
@@ -207,56 +433,328 @@
}
/**
- * Add the summary for the module.
+ * Get table header.
*
* @param text the table caption
* @param tableSummary the summary for the table
- * @param htmltree the content tree to which the table will be added
+ * @param tableStyle the table style
+ * @param tableHeader the table header
+ * @return a content object
+ */
+ public Content getTableHeader(String text, String tableSummary, HtmlStyle tableStyle,
+ List<String> tableHeader) {
+ return getTableHeader(getTableCaption(new RawHtml(text)), tableSummary, tableStyle, tableHeader);
+ }
+
+ /**
+ * Get table header.
+ *
+ * @param caption the table caption
+ * @param tableSummary the summary for the table
* @param tableStyle the table style
* @param tableHeader the table header
- * @param dirs the list of module directives
+ * @return a content object
*/
- public void addSummary(String text, String tableSummary, Content htmltree, HtmlStyle tableStyle,
- List<String> tableHeader, List<ModuleElement.Directive> dirs) {
+ public Content getTableHeader(Content caption, String tableSummary, HtmlStyle tableStyle,
+ List<String> tableHeader) {
Content table = (configuration.isOutputHtml5())
- ? HtmlTree.TABLE(tableStyle, getTableCaption(new RawHtml(text)))
- : HtmlTree.TABLE(tableStyle, tableSummary, getTableCaption(new RawHtml(text)));
+ ? HtmlTree.TABLE(tableStyle, caption)
+ : HtmlTree.TABLE(tableStyle, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
- Content tbody = new HtmlTree(HtmlTag.TBODY);
- addList(dirs, tbody);
+ return table;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addModulesSummary(Content summaryContentTree) {
+ if (display(requires) || display(additionalModules)) {
+ HtmlTree li = new HtmlTree(HtmlTag.LI);
+ li.addStyle(HtmlStyle.blockList);
+ addSummaryHeader(HtmlConstants.START_OF_MODULES_SUMMARY, SectionName.MODULES,
+ contents.navModules, li);
+ if (display(requires)) {
+ String text = configuration.getText("doclet.Requires_Summary");
+ String tableSummary = configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Requires_Summary"),
+ configuration.getText("doclet.modules"));
+ Content table = getTableHeader(text, tableSummary, HtmlStyle.requiresSummary, requiresTableHeader);
+ Content tbody = new HtmlTree(HtmlTag.TBODY);
+ addModulesList(requires, tbody);
+ table.addContent(tbody);
+ li.addContent(table);
+ }
+ // Display additional modules table in both "api" and "all" mode.
+ if (display(additionalModules)) {
+ String amrText = configuration.getText("doclet.Additional_Modules_Required_Summary");
+ String amrTableSummary = configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Additional_Modules_Required_Summary"),
+ configuration.getText("doclet.modules"));
+ Content amrTable = getTableHeader(amrText, amrTableSummary, HtmlStyle.requiresSummary, requiresTableHeader);
+ Content amrTbody = new HtmlTree(HtmlTag.TBODY);
+ addModulesList(additionalModules, amrTbody);
+ amrTable.addContent(amrTbody);
+ li.addContent(amrTable);
+ }
+ HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
+ summaryContentTree.addContent(ul);
+ }
+ }
+
+ /**
+ * Add the list of modules.
+ *
+ * @param mdleMap map of modules and modifiers
+ * @param tbody the content tree to which the list will be added
+ */
+ public void addModulesList(Map<ModuleElement, Content> mdleMap, Content tbody) {
+ boolean altColor = true;
+ for (ModuleElement m : mdleMap.keySet()) {
+ Content tdModifiers = HtmlTree.TD(HtmlStyle.colFirst, mdleMap.get(m));
+ Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
+ Content thModule = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colSecond, moduleLinkContent);
+ HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
+ tdSummary.addStyle(HtmlStyle.colLast);
+ addSummaryComment(m, tdSummary);
+ HtmlTree tr = HtmlTree.TR(tdModifiers);
+ tr.addContent(thModule);
+ tr.addContent(tdSummary);
+ tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
+ tbody.addContent(tr);
+ altColor = !altColor;
+ }
+ }
+
+ public void addPackagesSummary(Content summaryContentTree) {
+ if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)
+ || display(additionalPackages) || display(additionalOpenPackages)) {
+ HtmlTree li = new HtmlTree(HtmlTag.LI);
+ li.addStyle(HtmlStyle.blockList);
+ addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
+ contents.navPackages, li);
+ String tableSummary = configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Packages_Summary"),
+ configuration.getText("doclet.packages"));
+ if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)) {
+ addPackageSummary(tableSummary, li);
+ }
+ if (display(additionalPackages)) {
+ String aepText = configuration.getText("doclet.Additional_Exported_Packages_Summary");
+ String aepTableSummary = configuration.getText("doclet.Additional_Packages_Table_Summary",
+ configuration.getText("doclet.Additional_Exported_Packages_Summary"),
+ configuration.getText("doclet.modules"),
+ configuration.getText("doclet.packages"));
+ Content aepTable = getTableHeader(aepText, aepTableSummary, HtmlStyle.packagesSummary,
+ additionalPackagesTableHeader);
+ Content aepTbody = new HtmlTree(HtmlTag.TBODY);
+ addAdditionalPackages(aepTbody, additionalPackages);
+ aepTable.addContent(aepTbody);
+ li.addContent(aepTable);
+ }
+ if (display(additionalOpenPackages)) {
+ String aopText = configuration.getText("doclet.Additional_Opened_Packages_Summary");
+ String aopTableSummary = configuration.getText("doclet.Additional_Packages_Table_Summary",
+ configuration.getText("doclet.Additional_Opened_Packages_Summary"),
+ configuration.getText("doclet.modules"),
+ configuration.getText("doclet.packages"));
+ Content aopTable = getTableHeader(aopText, aopTableSummary, HtmlStyle.packagesSummary,
+ additionalPackagesTableHeader);
+ Content aopTbody = new HtmlTree(HtmlTag.TBODY);
+ addAdditionalPackages(aopTbody, additionalOpenPackages);
+ aopTable.addContent(aopTbody);
+ li.addContent(aopTable);
+ }
+ HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
+ summaryContentTree.addContent(ul);
+ }
+ }
+
+ /**
+ * Add the package summary for the module.
+ *
+ * @param tableSummary
+ * @param li
+ */
+ public void addPackageSummary(String tableSummary, HtmlTree li) {
+ Content caption;
+ Content tbody = getPackageTableRows();
+ if (showTabs()) {
+ caption = getTableCaption();
+ generateTableTabTypesScript(typeMap, modulePackageTypes, "packages");
+ } else {
+ ModulePackageTypes type = modulePackageTypes.iterator().next();
+ caption = getTableCaption(configuration.getContent(type.tableTabs().resourceKey()));
+ }
+ Content table = getTableHeader(caption, tableSummary, HtmlStyle.packagesSummary, exportedPackagesTableHeader);
table.addContent(tbody);
- htmltree.addContent(table);
+ li.addContent(table);
}
/**
- * Add the list of directives for the module.
+ * Returns true if the table tabs needs to be displayed.
+ *
+ * @return true if the tabs should be displayed
+ */
+ public boolean showTabs() {
+ int value;
+ for (ModulePackageTypes type : EnumSet.allOf(ModulePackageTypes.class)) {
+ value = type.tableTabs().value();
+ if ((value & packageTypesOr) == value) {
+ modulePackageTypes.add(type);
+ }
+ }
+ boolean showTabs = modulePackageTypes.size() > 1;
+ if (showTabs) {
+ modulePackageTypes.add(ModulePackageTypes.ALL);
+ }
+ return showTabs;
+ }
+
+ /**
+ * Get the summary table caption.
*
- * @param dirs the list of module directives
- * @param tbody the content tree to which the list is added
+ * @return the caption for the summary table
*/
- public void addList(List<ModuleElement.Directive> dirs, Content tbody) {
+ public Content getTableCaption() {
+ Content tabbedCaption = new HtmlTree(HtmlTag.CAPTION);
+ for (ModulePackageTypes type : modulePackageTypes) {
+ Content captionSpan;
+ Content span;
+ if (type.tableTabs().isDefaultTab()) {
+ captionSpan = HtmlTree.SPAN(configuration.getContent(type.tableTabs().resourceKey()));
+ span = HtmlTree.SPAN(type.tableTabs().tabId(),
+ HtmlStyle.activeTableTab, captionSpan);
+ } else {
+ captionSpan = HtmlTree.SPAN(getPackageTypeLinks(type));
+ span = HtmlTree.SPAN(type.tableTabs().tabId(),
+ HtmlStyle.tableTab, captionSpan);
+ }
+ Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, Contents.SPACE);
+ span.addContent(tabSpan);
+ tabbedCaption.addContent(span);
+ }
+ return tabbedCaption;
+ }
+
+ /**
+ * Get the package type links for the table caption.
+ *
+ * @param packageType the package type to be displayed as link
+ * @return the content tree for the package type link
+ */
+ public Content getPackageTypeLinks(ModulePackageTypes packageType) {
+ String jsShow = "javascript:showPkgs(" + packageType.tableTabs().value() + ");";
+ HtmlTree link = HtmlTree.A(jsShow, configuration.getContent(packageType.tableTabs().resourceKey()));
+ return link;
+ }
+
+ /**
+ * Get the package table rows.
+ *
+ * @return a content object
+ */
+ public Content getPackageTableRows() {
+ Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
- for (ModuleElement.Directive direct : dirs) {
- DirectiveKind kind = direct.getKind();
- switch (kind) {
- case REQUIRES:
- addRequiresList((ModuleElement.RequiresDirective) direct, tbody, altColor);
- break;
- case EXPORTS:
- addExportedPackagesList((ModuleElement.ExportsDirective) direct, tbody, altColor);
- break;
- case OPENS:
- //XXX ignore for now
- break;
- case USES:
- addUsesList((ModuleElement.UsesDirective) direct, tbody, altColor);
- break;
- case PROVIDES:
- addProvidesList((ModuleElement.ProvidesDirective) direct, tbody, altColor);
- break;
- default:
- throw new AssertionError("unknown directive kind: " + kind);
+ int counter = 0;
+ counter = addPackageTableRows(tbody, counter, ModulePackageTypes.EXPORTED, exportedPackages);
+ counter = addPackageTableRows(tbody, counter, ModulePackageTypes.OPENED, openedPackages);
+ // Show concealed packages only in "all" mode.
+ if (moduleMode == ModuleMode.ALL) {
+ for (PackageElement pkg : concealedPackages) {
+ Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
+ Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
+ HtmlTree tdModules = new HtmlTree(HtmlTag.TD);
+ tdModules.addStyle(HtmlStyle.colSecond);
+ tdModules.addContent(configuration.getText("doclet.None"));
+ HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
+ tdSummary.addStyle(HtmlStyle.colLast);
+ addSummaryComment(pkg, tdSummary);
+ HtmlTree tr = HtmlTree.TR(thPackage);
+ tr.addContent(tdModules);
+ tr.addContent(tdSummary);
+ tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
+ int pkgType = ModulePackageTypes.CONCEALED.tableTabs().value();
+ packageTypesOr = packageTypesOr | pkgType;
+ String tableId = "i" + counter;
+ counter++;
+ typeMap.put(tableId, pkgType);
+ tr.addAttr(HtmlAttr.ID, tableId);
+ tbody.addContent(tr);
+ altColor = !altColor;
}
+ }
+ return tbody;
+ }
+
+ public int addPackageTableRows(Content tbody, int counter, ModulePackageTypes pType,
+ Map<PackageElement,SortedSet<ModuleElement>> ap) {
+ boolean altColor = true;
+ for (Map.Entry<PackageElement, SortedSet<ModuleElement>> entry : ap.entrySet()) {
+ PackageElement pkg = entry.getKey();
+ SortedSet<ModuleElement> mdleList = entry.getValue();
+ Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
+ Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
+ HtmlTree tr = HtmlTree.TR(thPackage);
+ if (moduleMode == ModuleMode.ALL) {
+ HtmlTree tdModules = new HtmlTree(HtmlTag.TD);
+ tdModules.addStyle(HtmlStyle.colSecond);
+ if (!mdleList.isEmpty()) {
+ int sep = 0;
+ for (ModuleElement m : mdleList) {
+ if (sep > 0) {
+ tdModules.addContent(new HtmlTree(HtmlTag.BR));
+ }
+ tdModules.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
+ sep++;
+ }
+ } else {
+ tdModules.addContent(configuration.getText("doclet.All_Modules"));
+ }
+ tr.addContent(tdModules);
+ }
+ HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
+ tdSummary.addStyle(HtmlStyle.colLast);
+ addSummaryComment(pkg, tdSummary);
+ tr.addContent(tdSummary);
+ tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
+ int pkgType = pType.tableTabs().value();
+ packageTypesOr = packageTypesOr | pkgType;
+ String tableId = "i" + counter;
+ counter++;
+ typeMap.put(tableId, pkgType);
+ tr.addAttr(HtmlAttr.ID, tableId);
+ tbody.addContent(tr);
+ altColor = !altColor;
+ }
+ return counter;
+ }
+
+ /**
+ * Add the additional packages for the module being documented.
+ *
+ * @param tbody the content tree to which the table will be added
+ * @param ap additional packages to be added
+ */
+ public void addAdditionalPackages(Content tbody, Map<ModuleElement, SortedSet<PackageElement>> ap) {
+ boolean altColor = true;
+ for (Map.Entry<ModuleElement, SortedSet<PackageElement>> entry : ap.entrySet()) {
+ ModuleElement m = entry.getKey();
+ SortedSet<PackageElement> pkgList = entry.getValue();
+ Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
+ Content thModule = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, moduleLinkContent);
+ HtmlTree tdPackages = new HtmlTree(HtmlTag.TD);
+ tdPackages.addStyle(HtmlStyle.colLast);
+ String sep = "";
+ for (PackageElement pkg : pkgList) {
+ tdPackages.addContent(sep);
+ tdPackages.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
+ sep = " ";
+ }
+ HtmlTree tr = HtmlTree.TR(thModule);
+ tr.addContent(tdPackages);
+ tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
+ tbody.addContent(tr);
altColor = !altColor;
}
}
@@ -264,154 +762,39 @@
/**
* {@inheritDoc}
*/
- @Override
- public void addModulesSummary(Content summaryContentTree) {
- List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.REQUIRES);
- if (dirs != null && !dirs.isEmpty()) {
- HtmlTree li = new HtmlTree(HtmlTag.LI);
- li.addStyle(HtmlStyle.blockList);
- addSummaryHeader(HtmlConstants.START_OF_MODULES_SUMMARY, SectionName.MODULES,
- contents.navModules, li);
- String text = configuration.getText("doclet.Requires_Summary");
- String tableSummary = configuration.getText("doclet.Member_Table_Summary",
- configuration.getText("doclet.Requires_Summary"),
- configuration.getText("doclet.modules"));
- addRequiresSummary(text, tableSummary, dirs, li);
- HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
- summaryContentTree.addContent(ul);
- }
- }
-
- /**
- * Add the requires summary for the module.
- *
- * @param text the table caption
- * @param tableSummary the summary for the table
- * @param dirs the list of module directives
- * @param htmltree the content tree to which the table will be added
- */
- public void addRequiresSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
- Content htmltree) {
- addSummary(text, tableSummary, htmltree, HtmlStyle.requiresSummary, requiresTableHeader, dirs);
- }
-
- /**
- * Add the requires directive list for the module.
- *
- * @param direct the requires directive
- * @param tbody the content tree to which the directive will be added
- * @param altColor true if altColor style should be used or false if rowColor style should be used
- */
- public void addRequiresList(ModuleElement.RequiresDirective direct, Content tbody, boolean altColor) {
- ModuleElement m = direct.getDependency();
- Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName().toString()));
- Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, moduleLinkContent);
- HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
- tdSummary.addStyle(HtmlStyle.colLast);
- addSummaryComment(m, tdSummary);
- HtmlTree tr = HtmlTree.TR(thPackage);
- tr.addContent(tdSummary);
- tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
- tbody.addContent(tr);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addPackagesSummary(Content summaryContentTree) {
- List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.EXPORTS);
- if (dirs != null && !dirs.isEmpty()) {
- HtmlTree li = new HtmlTree(HtmlTag.LI);
- li.addStyle(HtmlStyle.blockList);
- addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
- contents.navPackages, li);
- String text = configuration.getText("doclet.Exported_Packages_Summary");
- String tableSummary = configuration.getText("doclet.Member_Table_Summary",
- configuration.getText("doclet.Exported_Packages_Summary"),
- configuration.getText("doclet.packages"));
- addExportedPackagesSummary(text, tableSummary, dirs, li);
- HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
- summaryContentTree.addContent(ul);
- }
- }
-
- /**
- * Add the exported packages summary for the module.
- *
- * @param text the table caption
- * @param tableSummary the summary for the table
- * @param dirs the list of module directives
- * @param htmltree the content tree to which the table will be added
- */
- public void addExportedPackagesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
- Content htmltree) {
- addSummary(text, tableSummary, htmltree, HtmlStyle.packagesSummary, exportedPackagesTableHeader, dirs);
- }
-
- /**
- * Add the exported packages list for the module.
- *
- * @param direct the requires directive
- * @param tbody the content tree to which the directive will be added
- * @param altColor true if altColor style should be used or false if rowColor style should be used
- */
- public void addExportedPackagesList(ModuleElement.ExportsDirective direct, Content tbody, boolean altColor) {
- PackageElement pkg = direct.getPackage();
- Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
- Content tdPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
- HtmlTree thModules = new HtmlTree(HtmlTag.TD);
- thModules.addStyle(HtmlStyle.colSecond);
- List<? extends ModuleElement> targetModules = direct.getTargetModules();
- if (targetModules != null) {
- List<? extends ModuleElement> mElements = direct.getTargetModules();
- for (int i = 0; i < mElements.size(); i++) {
- if (i > 0) {
- thModules.addContent(new HtmlTree(HtmlTag.BR));
- }
- ModuleElement m = mElements.get(i);
- thModules.addContent(new StringContent(m.getQualifiedName().toString()));
- }
- } else {
- thModules.addContent(configuration.getText("doclet.All_Modules"));
- }
- HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
- tdSummary.addStyle(HtmlStyle.colLast);
- addSummaryComment(pkg, tdSummary);
- HtmlTree tr = HtmlTree.TR(tdPackage);
- tr.addContent(thModules);
- tr.addContent(tdSummary);
- tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
- tbody.addContent(tr);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public void addServicesSummary(Content summaryContentTree) {
- List<ModuleElement.Directive> usesDirs = directiveMap.get(DirectiveKind.USES);
- List<ModuleElement.Directive> providesDirs = directiveMap.get(DirectiveKind.PROVIDES);
- if ((usesDirs != null && !usesDirs.isEmpty()) || (providesDirs != null && !providesDirs.isEmpty())) {
+ if (display(uses) || display(provides)) {
HtmlTree li = new HtmlTree(HtmlTag.LI);
li.addStyle(HtmlStyle.blockList);
addSummaryHeader(HtmlConstants.START_OF_SERVICES_SUMMARY, SectionName.SERVICES,
contents.navServices, li);
String text;
String tableSummary;
- if (usesDirs != null && !usesDirs.isEmpty()) {
+ if (display(uses)) {
text = configuration.getText("doclet.Uses_Summary");
tableSummary = configuration.getText("doclet.Member_Table_Summary",
configuration.getText("doclet.Uses_Summary"),
configuration.getText("doclet.types"));
- addUsesSummary(text, tableSummary, usesDirs, li);
+ Content table = getTableHeader(text, tableSummary, HtmlStyle.usesSummary, usesTableHeader);
+ Content tbody = new HtmlTree(HtmlTag.TBODY);
+ addUsesList(tbody);
+ if (!tbody.isEmpty()) {
+ table.addContent(tbody);
+ li.addContent(table);
}
- if (providesDirs != null && !providesDirs.isEmpty()) {
+ }
+ if (display(provides)) {
text = configuration.getText("doclet.Provides_Summary");
tableSummary = configuration.getText("doclet.Member_Table_Summary",
configuration.getText("doclet.Provides_Summary"),
configuration.getText("doclet.types"));
- addProvidesSummary(text, tableSummary, providesDirs, li);
+ Content table = getTableHeader(text, tableSummary, HtmlStyle.providesSummary, providesTableHeader);
+ Content tbody = new HtmlTree(HtmlTag.TBODY);
+ addProvidesList(tbody);
+ if (!tbody.isEmpty()) {
+ table.addContent(tbody);
+ li.addContent(table);
+ }
}
HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
summaryContentTree.addContent(ul);
@@ -419,79 +802,94 @@
}
/**
- * Add the uses summary for the module.
- *
- * @param text the table caption
- * @param tableSummary the summary for the table
- * @param dirs the list of module directives
- * @param htmltree the content tree to which the table will be added
- */
- public void addUsesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
- Content htmltree) {
- addSummary(text, tableSummary, htmltree, HtmlStyle.usesSummary, usesTableHeader, dirs);
- }
-
- /**
* Add the uses list for the module.
*
- * @param direct the requires directive
* @param tbody the content tree to which the directive will be added
- * @param altColor true if altColor style should be used or false if rowColor style should be used
*/
- public void addUsesList(ModuleElement.UsesDirective direct, Content tbody, boolean altColor) {
- TypeElement type = direct.getService();
- Content typeLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, type));
- Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, typeLinkContent);
- HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
+ public void addUsesList(Content tbody) {
+ boolean altColor = true;
+ Content typeLinkContent;
+ Content thType;
+ HtmlTree tdSummary;
+ Content description;
+ for (TypeElement t : uses) {
+ // For each uses directive in the module declaration, if we are in the "api" mode and
+ // if there are service types listed using @uses javadoc tag, check if the service type in
+ // the uses directive is specified using the @uses tag. If not, we do not display the
+ // service type in the "api" mode.
+ if (moduleMode == ModuleMode.API && display(usesTrees) && !usesTrees.containsKey(t)) {
+ continue;
+ }
+ typeLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, t));
+ thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, typeLinkContent);
+ tdSummary = new HtmlTree(HtmlTag.TD);
tdSummary.addStyle(HtmlStyle.colLast);
- addSummaryComment(type, tdSummary);
- HtmlTree tr = HtmlTree.TR(thPackage);
+ if (display(usesTrees)) {
+ description = usesTrees.get(t);
+ if (description != null) {
+ tdSummary.addContent(description);
+ }
+ }
+ addSummaryComment(t, tdSummary);
+ HtmlTree tr = HtmlTree.TR(thType);
tr.addContent(tdSummary);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
+ altColor = !altColor;
+ }
}
/**
- * Add the provides summary for the module.
+ * Add the provides list for the module.
*
- * @param text the table caption
- * @param tableSummary the summary for the table
- * @param dirs the list of module directives
- * @param htmltree the content tree to which the table will be added
+ * @param tbody the content tree to which the directive will be added
*/
- public void addProvidesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
- Content htmltree) {
- addSummary(text, tableSummary, htmltree, HtmlStyle.providesSummary, providesTableHeader, dirs);
+ public void addProvidesList(Content tbody) {
+ boolean altColor = true;
+ TypeElement srv;
+ SortedSet<TypeElement> implSet;
+ Content description;
+ for (Map.Entry<TypeElement, SortedSet<TypeElement>> entry : provides.entrySet()) {
+ srv = entry.getKey();
+ // For each provides directive in the module declaration, if we are in the "api" mode and
+ // if there are service types listed using @provides javadoc tag, check if the service type in
+ // the provides directive is specified using the @provides tag. If not, we do not display the
+ // service type in the "api" mode.
+ if (moduleMode == ModuleMode.API && display(providesTrees) && !providesTrees.containsKey(srv)) {
+ continue;
}
-
- /**
- * Add the exported packages list for the module.
- *
- * @param direct the requires directive
- * @param tbody the content tree to which the directive will be added
- * @param altColor true if altColor style should be used or false if rowColor style should be used
- */
- public void addProvidesList(ModuleElement.ProvidesDirective direct, Content tbody, boolean altColor) {
- List<? extends TypeElement> impls = direct.getImplementations();
- for (TypeElement impl : impls) {
- TypeElement srv = direct.getService();
- Content implLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl));
+ implSet = entry.getValue();
Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv));
HtmlTree thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, srvLinkContent);
- thType.addContent(new HtmlTree(HtmlTag.BR));
- thType.addContent("(");
- HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
- thType.addContent(implSpan);
- thType.addContent(Contents.SPACE);
- thType.addContent(implLinkContent);
- thType.addContent(")");
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
+ if (display(providesTrees)) {
+ description = providesTrees.get(srv);
+ if (description != null) {
+ tdDesc.addContent(description);
+ }
+ }
addSummaryComment(srv, tdDesc);
+ // Only display the implementation details in the "all" mode.
+ if (moduleMode == ModuleMode.ALL && !implSet.isEmpty()) {
+ tdDesc.addContent(new HtmlTree(HtmlTag.BR));
+ tdDesc.addContent("(");
+ HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
+ tdDesc.addContent(implSpan);
+ tdDesc.addContent(Contents.SPACE);
+ String sep = "";
+ for (TypeElement impl : implSet) {
+ tdDesc.addContent(sep);
+ tdDesc.addContent(getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl)));
+ sep = ", ";
+ }
+ tdDesc.addContent(")");
+ }
HtmlTree tr = HtmlTree.TR(thType);
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
tbody.addContent(tr);
+ altColor = !altColor;
}
}
@@ -574,15 +972,17 @@
? getHyperLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription)
: contents.navModuleDescription);
addNavGap(liNav);
- liNav.addContent(showDirectives(DirectiveKind.REQUIRES)
+ liNav.addContent((display(requires) || display(additionalModules))
? getHyperLink(SectionName.MODULES, contents.navModules)
: contents.navModules);
addNavGap(liNav);
- liNav.addContent(showDirectives(DirectiveKind.EXPORTS)
+ liNav.addContent((display(exportedPackages) || display(openedPackages) || display(concealedPackages)
+ || display(additionalPackages) || display(additionalOpenPackages))
? getHyperLink(SectionName.PACKAGES, contents.navPackages)
: contents.navPackages);
addNavGap(liNav);
- liNav.addContent((showDirectives(DirectiveKind.USES) || showDirectives(DirectiveKind.PROVIDES))
+ liNav.addContent((display(uses) || (moduleMode == ModuleMode.API && display(usesTrees))
+ || display(provides) || (moduleMode == ModuleMode.API && display(providesTrees)))
? getHyperLink(SectionName.SERVICES, contents.navServices)
: contents.navServices);
ulNav.addContent(liNav);
@@ -590,16 +990,6 @@
}
/**
- * Return true if the directive should be displayed.
- *
- * @param dirKind the kind of directive for the module
- * @return true if the directive should be displayed
- */
- private boolean showDirectives(DirectiveKind dirKind) {
- return directiveMap.get(dirKind) != null && !directiveMap.get(dirKind).isEmpty();
- }
-
- /**
* {@inheritDoc}
*/
@Override
@@ -629,6 +1019,8 @@
/**
* {@inheritDoc}
+ *
+ * @throws jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException
*/
@Override
public void printDocument(Content contentTree) throws DocFileIOException {