8253559: The INDEX page should link to Serialized Form and Constant Values pages

Reviewed-by: hannesw
This commit is contained in:
Jonathan Gibbons 2020-10-16 22:15:52 +00:00
parent e66c6bb9d5
commit 83ea863122
14 changed files with 100 additions and 44 deletions

@ -48,6 +48,7 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
/**
@ -60,11 +61,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
*/
public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements ConstantsSummaryWriter {
/**
* The configuration used in this run of the standard doclet.
*/
HtmlConfiguration configuration;
/**
* The current class being documented.
*/
@ -81,6 +77,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
private final BodyContents bodyContents = new BodyContents();
private boolean hasConstants = false;
/**
* Construct a ConstantsSummaryWriter.
* @param configuration the configuration used in this run
@ -88,7 +86,6 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
*/
public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) {
super(configuration, DocPaths.CONSTANT_VALUES);
this.configuration = configuration;
constantsTableHeader = new TableHeader(
contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel);
this.navBar = new Navigation(null, configuration, PageMode.CONSTANT_VALUES, path);
@ -184,6 +181,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
@Override
public void addClassConstant(Content summariesTree, Content classConstantTree) {
summaryTree.add(classConstantTree);
hasConstants = true;
}
@Override
@ -283,5 +281,10 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
public void printDocument(Content contentTree) throws DocFileIOException {
contentTree.add(bodyContents);
printHtmlDocument(null, "summary of constants", contentTree);
if (hasConstants && configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Constants_Summary"), path));
}
}
}

@ -25,6 +25,7 @@
package jdk.javadoc.internal.doclets.formats.html;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Objects;
import java.util.regex.Matcher;
@ -103,7 +104,6 @@ public class Contents {
public final Content fieldDetailsLabel;
public final Content fieldSummaryLabel;
public final Content fields;
public final Content framesLabel;
public final Content fromLabel;
public final Content functionalInterface;
public final Content functionalInterfaceMessage;
@ -141,7 +141,6 @@ public class Contents {
public final Content navServices;
public final Content nestedClassSummary;
public final Content newPage;
public final Content noFramesLabel;
public final Content noScriptMessage;
public final Content openModuleLabel;
public final Content openedTo;
@ -189,10 +188,10 @@ public class Contents {
Contents(HtmlConfiguration configuration) {
this.resources = configuration.getDocResources();
allClassesLabel = getNonBreakContent("doclet.All_Classes");
allClassesLabel = getNonBreakResource("doclet.All_Classes");
allImplementedInterfacesLabel = getContent("doclet.All_Implemented_Interfaces");
allModulesLabel = getNonBreakContent("doclet.All_Modules");
allPackagesLabel = getNonBreakContent("doclet.All_Packages");
allModulesLabel = getNonBreakResource("doclet.All_Modules");
allPackagesLabel = getNonBreakResource("doclet.All_Packages");
allSuperinterfacesLabel = getContent("doclet.All_Superinterfaces");
also = getContent("doclet.also");
annotationTypeOptionalMemberLabel = getContent("doclet.Annotation_Type_Optional_Member");
@ -239,7 +238,6 @@ public class Contents {
fieldSummaryLabel = getContent("doclet.Field_Summary");
fieldLabel = getContent("doclet.Field");
fields = getContent("doclet.Fields");
framesLabel = getContent("doclet.Frames");
fromLabel = getContent("doclet.From");
functionalInterface = getContent("doclet.Functional_Interface");
functionalInterfaceMessage = getContent("doclet.Functional_Interface_Message");
@ -277,7 +275,6 @@ public class Contents {
navServices = getContent("doclet.navServices");
nestedClassSummary = getContent("doclet.Nested_Class_Summary");
newPage = new Comment(resources.getText("doclet.New_Page"));
noFramesLabel = getNonBreakContent("doclet.No_Frames");
noScriptMessage = getContent("doclet.No_Script_Message");
openedTo = getContent("doclet.OpenedTo");
openModuleLabel = getContent("doclet.Open_Module");
@ -400,6 +397,27 @@ public class Contents {
return c;
}
/**
* Returns content composed of items joined together with the specified separator.
*
* @param separator the separator
* @param items the items
* @return the content
*/
public Content join(Content separator, Collection<Content> items) {
Content result = new ContentBuilder();
boolean first = true;
for (Content c : items) {
if (first) {
first = false;
} else {
result.add(separator);
}
result.add(c);
}
return result;
}
/**
* Gets a {@code Content} object, containing the string for
* a given key in the doclet's resources, substituting
@ -409,8 +427,19 @@ public class Contents {
* @param key the key for the desired string
* @return a content tree for the string
*/
private Content getNonBreakContent(String key) {
String text = resources.getText(key); // TODO: cache
private Content getNonBreakResource(String key) {
return getNonBreakString(resources.getText(key));
}
/**
* Gets a {@code Content} object for a string, substituting
* <code>&nbsp;</code> for any space characters found in
* the named resource string.
*
* @param text the string
* @return a content tree for the string
*/
public Content getNonBreakString(String text) {
Content c = new ContentBuilder();
int start = 0;
int p;

@ -49,6 +49,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder.DeprEl
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
/**
* Generate File to list all the deprecated classes and class members with the
@ -300,6 +301,11 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
String description = "deprecated elements";
body.add(bodyContents);
printHtmlDocument(null, description, body);
if (!deprapi.isEmpty() && configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Deprecated_API"), path));
}
}
/**

@ -171,7 +171,6 @@ public class HtmlDoclet extends AbstractDoclet {
if (options.createIndex()) {
SystemPropertiesWriter.generate(configuration);
configuration.mainIndex.addElements();
IndexWriter.generate(configuration);
IndexBuilder allClassesIndex = new IndexBuilder(configuration, nodeprecated, true);
allClassesIndex.addElements();
AllClassesIndexWriter.generate(configuration, allClassesIndex);
@ -179,6 +178,7 @@ public class HtmlDoclet extends AbstractDoclet {
AllPackagesIndexWriter.generate(configuration);
}
configuration.mainIndex.createSearchIndexFiles();
IndexWriter.generate(configuration);
}
if (options.createOverview()) {

@ -28,6 +28,8 @@ package jdk.javadoc.internal.doclets.formats.html;
import java.util.List;
import java.util.ListIterator;
import java.util.SortedSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@ -369,22 +371,14 @@ public class IndexWriter extends HtmlDocletWriter {
}
contentTree.add(new HtmlTree(TagName.BR));
contentTree.add(links.createLink(pathToRoot.resolve(DocPaths.ALLCLASSES_INDEX),
contents.allClassesLabel));
if (!configuration.packages.isEmpty()) {
contentTree.add(getVerticalSeparator());
contentTree.add(links.createLink(pathToRoot.resolve(DocPaths.ALLPACKAGES_INDEX),
contents.allPackagesLabel));
}
boolean anySystemProperties = !mainIndex.getItems(DocTree.Kind.SYSTEM_PROPERTY).isEmpty();
if (anySystemProperties) {
contentTree.add(getVerticalSeparator());
contentTree.add(links.createLink(pathToRoot.resolve(DocPaths.SYSTEM_PROPERTIES),
contents.systemPropertiesLabel));
}
List<Content> pageLinks = Stream.of(IndexItem.Category.values())
.flatMap(c -> mainIndex.getItems(c).stream())
.filter(i -> !(i.isElementItem() || i.isTagItem()))
.sorted((i1,i2)-> utils.compareStrings(i1.getLabel(), i2.getLabel()))
.map(i -> links.createLink(pathToRoot.resolve(i.getUrl()),
contents.getNonBreakString(i.getLabel())))
.collect(Collectors.toList());
contentTree.add(contents.join(getVerticalSeparator(), pageLinks));
}
/**

@ -40,6 +40,7 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.SerializedFormWriter;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
/**
* Generates the Serialized Form Information Page, <i>serialized-form.html</i>.
@ -250,6 +251,11 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
public void printDocument(Content serializedTree) throws DocFileIOException {
serializedTree.add(bodyContents);
printHtmlDocument(null, "serialized forms", serializedTree);
if (configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Serialized_Form"), path));
}
}
/**

@ -126,6 +126,10 @@ public class SystemPropertiesWriter extends HtmlDocletWriter {
.addMainContent(mainContent)
.setFooter(footer));
printHtmlDocument(null, "system properties", body);
if (configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
}
}
/**

@ -112,8 +112,6 @@ doclet.Functional_Interface_Message=\
This is a functional interface and can therefore be used as the assignment target for a lambda \
expression or method reference.
doclet.also=also
doclet.Frames=Frames
doclet.No_Frames=No Frames
doclet.Package_Hierarchies=Package Hierarchies:
doclet.Hierarchy_For_Package=Hierarchy For Package {0}
doclet.Hierarchy_For_All_Packages=Hierarchy For All Packages

@ -49,6 +49,7 @@ public class DeprecatedAPIListBuilder {
private final Map<DeprElementKind, SortedSet<Element>> deprecatedMap;
private final BaseConfiguration configuration;
private final Utils utils;
public enum DeprElementKind {
REMOVAL,
MODULE,
@ -65,6 +66,7 @@ public class DeprecatedAPIListBuilder {
ENUM_CONSTANT,
ANNOTATION_TYPE_MEMBER // no ElementKind mapping
};
/**
* Constructor.
*
@ -81,6 +83,10 @@ public class DeprecatedAPIListBuilder {
buildDeprecatedAPIInfo();
}
public boolean isEmpty() {
return deprecatedMap.values().stream().allMatch(Collection::isEmpty);
}
/**
* Build the sorted list of all the deprecated APIs in this run.
* Build separate lists for deprecated modules, packages, classes, constructors,

@ -163,9 +163,13 @@ public class IndexBuilder {
public void add(IndexItem item) {
Objects.requireNonNull(item);
itemsByFirstChar.computeIfAbsent(keyCharacter(item.getLabel()),
if (item.isElementItem() || item.isTagItem()) {
// don't put summary-page items in the A-Z index:
// they are listed separately, at the top of the index page
itemsByFirstChar.computeIfAbsent(keyCharacter(item.getLabel()),
c -> new TreeSet<>(mainComparator))
.add(item);
.add(item);
}
itemsByCategory.computeIfAbsent(item.getCategory(),
c -> new TreeSet<>(mainComparator))
@ -210,7 +214,7 @@ public class IndexBuilder {
public SortedSet<IndexItem> getItems(DocTree.Kind kind) {
Objects.requireNonNull(kind);
return itemsByCategory.getOrDefault(IndexItem.Category.TAGS, Collections.emptySortedSet()).stream()
.filter(i -> i.getDocTree().getKind() == kind)
.filter(i -> i.isKind(kind))
.collect(Collectors.toCollection(() -> new TreeSet<>(mainComparator)));
}

@ -421,6 +421,16 @@ public class IndexItem {
return getDocTree() != null;
}
/**
* Returns {@code true} if this index is for a specific kind of tag in a doc comment.
*
* @return {@code true} if this index is for a specific kind of tag in a doc comment
*/
public boolean isKind(DocTree.Kind kind) {
DocTree dt = getDocTree();
return dt != null && dt.getKind() == kind;
}
/**
* Sets the URL for the item, when it cannot otherwise be inferred from other fields.
*

@ -2660,7 +2660,7 @@ public class Utils {
* The entries may come from the AST and DocCommentParser, or may be autromatically
* generated comments for mandated elements and JavaFX properties.
*
* @see CommentUtils.dcInfoMap
* @see CommentUtils#dcInfoMap
*/
private final Map<Element, DocCommentInfo> dcTreeCache = new LinkedHashMap<>();

@ -70,10 +70,6 @@ public class TestPackagePage extends JavadocTester {
<li><a href="com/pkg/package-summary.html">Package</a></li>""");
}
private static final String[][] TEST1 = {
};
@Test
public void testMultiplePackages() {
javadoc("-d", "out-2",

@ -23,7 +23,7 @@
/*
* @test
* @bug 8215038 8239487 8240476
* @bug 8215038 8239487 8240476 8253559
* @summary Add a page that lists all system properties
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@ -63,7 +63,7 @@ public class TestSystemPropertyPage extends JavadocTester {
checkOutput("index-all.html", true,
"""
<a href="system-properties.html">System Properties</a>""");
<a href="system-properties.html">System&nbsp;Properties</a>""");
checkOutput("system-properties.html", true,
"""