Skip to content
Permalink
Browse files

8239876: Improve SearchIndexItem

Reviewed-by: jjg
  • Loading branch information
pavelrappo committed Feb 26, 2020
1 parent 9b12c80 commit e8c32ccb2f1ca982fd4e51efc1c56d5d426dfe79
@@ -27,8 +27,11 @@

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
@@ -74,6 +77,8 @@

protected Navigation navBar;

protected final Map<Character, List<SearchIndexItem>> tagSearchIndexMap;

/**
* This constructor will be used by {@link SplitIndexWriter}. Initializes
* path to this file and relative path from this file.
@@ -88,6 +93,9 @@ protected AbstractIndexWriter(HtmlConfiguration configuration,
super(configuration, path);
this.indexBuilder = indexBuilder;
this.navBar = new Navigation(null, configuration, PageMode.INDEX, path);
Collection<SearchIndexItem> items =
searchItems.get(SearchIndexItem.Category.SEARCH_TAGS);
this.tagSearchIndexMap = buildSearchTagIndex(items);
}

/**
@@ -182,29 +190,29 @@ protected void addDescription(Content dl, Element element) {
public Void visitModule(ModuleElement e, Void p) {
if (configuration.showModules) {
addDescription(e, dl, si);
configuration.moduleSearchIndex.add(si);
searchItems.add(si);
}
return null;
}

@Override
public Void visitPackage(PackageElement e, Void p) {
addDescription(e, dl, si);
configuration.packageSearchIndex.add(si);
searchItems.add(si);
return null;
}

@Override
public Void visitType(TypeElement e, Void p) {
addDescription(e, dl, si);
configuration.typeSearchIndex.add(si);
searchItems.add(si);
return null;
}

@Override
protected Void defaultAction(Element e, Void p) {
addDescription(e, dl, si);
configuration.memberSearchIndex.add(si);
searchItems.add(si);
return null;
}

@@ -424,32 +432,32 @@ public String getNameForIndex(String unicode) {
protected void createSearchIndexFiles() throws DocFileIOException {
if (configuration.showModules) {
createSearchIndexFile(DocPaths.MODULE_SEARCH_INDEX_JS,
configuration.moduleSearchIndex,
searchItems.get(SearchIndexItem.Category.MODULES),
"moduleSearchIndex");
}
if (!configuration.packages.isEmpty()) {
SearchIndexItem si = new SearchIndexItem();
si.setCategory(SearchIndexItem.Category.PACKAGES);
si.setLabel(resources.getText("doclet.All_Packages"));
si.setUrl(DocPaths.ALLPACKAGES_INDEX.getPath());
configuration.packageSearchIndex.add(si);
searchItems.add(si);
}
createSearchIndexFile(DocPaths.PACKAGE_SEARCH_INDEX_JS,
configuration.packageSearchIndex,
searchItems.get(SearchIndexItem.Category.PACKAGES),
"packageSearchIndex");
SearchIndexItem si = new SearchIndexItem();
si.setCategory(SearchIndexItem.Category.TYPES);
si.setLabel(resources.getText("doclet.All_Classes"));
si.setUrl(DocPaths.ALLCLASSES_INDEX.getPath());
configuration.typeSearchIndex.add(si);
searchItems.add(si);
createSearchIndexFile(DocPaths.TYPE_SEARCH_INDEX_JS,
configuration.typeSearchIndex,
searchItems.get(SearchIndexItem.Category.TYPES),
"typeSearchIndex");
createSearchIndexFile(DocPaths.MEMBER_SEARCH_INDEX_JS,
configuration.memberSearchIndex,
searchItems.get(SearchIndexItem.Category.MEMBERS),
"memberSearchIndex");
createSearchIndexFile(DocPaths.TAG_SEARCH_INDEX_JS,
configuration.tagSearchIndex,
searchItems.get(SearchIndexItem.Category.SEARCH_TAGS),
"tagSearchIndex");
}

@@ -466,6 +474,8 @@ protected void createSearchIndexFile(DocPath searchIndexJS,
String varName)
throws DocFileIOException
{
// The file needs to be created even if there are no searchIndex items
// File could be written straight-through, without an intermediate StringBuilder
if (!searchIndex.isEmpty()) {
StringBuilder searchVar = new StringBuilder("[");
boolean first = true;
@@ -488,4 +498,18 @@ protected void createSearchIndexFile(DocPath searchIndexJS,
}
}
}

protected static Map<Character, List<SearchIndexItem>> buildSearchTagIndex(
Collection<? extends SearchIndexItem> searchItems)
{
Map<Character, List<SearchIndexItem>> map = new HashMap<>();
for (SearchIndexItem sii : searchItems) {
String tagLabel = sii.getLabel();
Character unicode = (tagLabel.length() == 0)
? '*'
: Character.toUpperCase(tagLabel.charAt(0));
map.computeIfAbsent(unicode, k -> new ArrayList<>()).add(sii);
}
return map;
}
}
@@ -91,19 +91,7 @@
*/
public TypeElement currentTypeElement = null; // Set this TypeElement in the ClassWriter.

protected SortedSet<SearchIndexItem> memberSearchIndex;

protected SortedSet<SearchIndexItem> moduleSearchIndex;

protected SortedSet<SearchIndexItem> packageSearchIndex;

protected SortedSet<SearchIndexItem> tagSearchIndex;

protected SortedSet<SearchIndexItem> typeSearchIndex;

protected Map<Character, List<SearchIndexItem>> tagSearchIndexMap = new HashMap<>();

protected Set<Character> tagSearchIndexKeys;
protected SearchIndexItems searchItems;

public final Contents contents;

@@ -349,17 +337,6 @@ public boolean showMessage(Element e, String key) {
return (e == null || workArounds.haveDocLint());
}

protected void buildSearchTagIndex() {
for (SearchIndexItem sii : tagSearchIndex) {
String tagLabel = sii.getLabel();
Character unicode = (tagLabel.length() == 0)
? '*'
: Character.toUpperCase(tagLabel.charAt(0));
tagSearchIndexMap.computeIfAbsent(unicode, k -> new ArrayList<>()).add(sii);
}
tagSearchIndexKeys = tagSearchIndexMap.keySet();
}

@Override
protected boolean finishOptionSettings0() throws DocletException {
if (options.docEncoding() == null) {
@@ -384,10 +361,6 @@ protected boolean finishOptionSettings0() throws DocletException {
@Override
protected void initConfiguration(DocletEnvironment docEnv) {
super.initConfiguration(docEnv);
memberSearchIndex = new TreeSet<>(utils.makeGenericSearchIndexComparator());
moduleSearchIndex = new TreeSet<>(utils.makeGenericSearchIndexComparator());
packageSearchIndex = new TreeSet<>(utils.makeGenericSearchIndexComparator());
tagSearchIndex = new TreeSet<>(utils.makeGenericSearchIndexComparator());
typeSearchIndex = new TreeSet<>(utils.makeTypeSearchIndexComparator());
searchItems = new SearchIndexItems(utils);
}
}
@@ -169,7 +169,6 @@ protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree)

if (options.createIndex()) {
IndexBuilder indexBuilder = new IndexBuilder(configuration, nodeprecated);
configuration.buildSearchTagIndex();
if (options.splitIndex()) {
SplitIndexWriter.generate(configuration, indexBuilder);
} else {
@@ -153,6 +153,8 @@
*/
public final HtmlConfiguration configuration;

protected final SearchIndexItems searchItems;

protected final HtmlOptions options;

protected final Utils utils;
@@ -210,6 +212,7 @@
*/
public HtmlDocletWriter(HtmlConfiguration configuration, DocPath path) {
this.configuration = configuration;
this.searchItems = configuration.searchItems;
this.options = configuration.getOptions();
this.contents = configuration.contents;
this.messages = configuration.messages;
@@ -101,6 +101,10 @@ public String getDescription() {
return description;
}

protected Category getCategory() {
return category;
}

public void setSystemProperty(boolean value) {
systemProperty = value;
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2020, 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 jdk.javadoc.internal.doclets.toolkit.util.Utils;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

/**
* A container for organizing {@linkplain SearchIndexItem search items}
* by {@linkplain SearchIndexItem.Category category}.
*
* <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 final class SearchIndexItems {

private final Map<SearchIndexItem.Category, Set<SearchIndexItem>> items = new HashMap<>();
private final Utils utils;

public SearchIndexItems(Utils utils) {
this.utils = Objects.requireNonNull(utils);
}

/**
* Adds the specified item to this container.
*
* @param item
* the item to add
*/
public void add(SearchIndexItem item) {
Objects.requireNonNull(item);
items.computeIfAbsent(item.getCategory(), this::newSetForCategory)
.add(item);
}

private Set<SearchIndexItem> newSetForCategory(SearchIndexItem.Category category) {
final Comparator<SearchIndexItem> cmp;
if (category == SearchIndexItem.Category.TYPES) {
cmp = utils.makeTypeSearchIndexComparator();
} else {
cmp = utils.makeGenericSearchIndexComparator();
}
return new TreeSet<>(cmp);
}

/**
* Retrieves the items of the specified category from this container.
*
* <p> The returned collection is either empty, if there are no items
* of the specified category, or contains only items {@code i} such that
* {@code i.getCategory().equals(cat)}. In any case, the returned collection
* is unmodifiable.
*
* @param cat
* the category of the items to retrieve
*
* @return a collection of items of the specified category
*/
public Collection<SearchIndexItem> get(SearchIndexItem.Category cat) {
Objects.requireNonNull(cat);
Set<SearchIndexItem> col = items.getOrDefault(cat, Set.of());
return Collections.unmodifiableCollection(col);
}
}
@@ -102,16 +102,16 @@ protected void generateIndexFile() throws DocFileIOException {
HtmlTree divTree = new HtmlTree(HtmlTag.DIV);
divTree.setStyle(HtmlStyle.contentContainer);
elements = new TreeSet<>(indexBuilder.asMap().keySet());
elements.addAll(configuration.tagSearchIndexKeys);
elements.addAll(tagSearchIndexMap.keySet());
addLinksForIndexes(divTree);
for (Character unicode : elements) {
if (configuration.tagSearchIndexMap.get(unicode) == null) {
if (tagSearchIndexMap.get(unicode) == null) {
addContents(unicode, indexBuilder.getMemberList(unicode), divTree);
} else if (indexBuilder.getMemberList(unicode) == null) {
addSearchContents(unicode, configuration.tagSearchIndexMap.get(unicode), divTree);
addSearchContents(unicode, tagSearchIndexMap.get(unicode), divTree);
} else {
addContents(unicode, indexBuilder.getMemberList(unicode),
configuration.tagSearchIndexMap.get(unicode), divTree);
tagSearchIndexMap.get(unicode), divTree);
}
}
addLinksForIndexes(divTree);
@@ -137,22 +137,22 @@ protected void generateIndexFile() throws DocFileIOException {
* @param contentTree the content tree to which the links for indexes will be added
*/
protected void addLinksForIndexes(Content contentTree) {
for (Object ch : elements) {
for (Character ch : elements) {
String unicode = ch.toString();
contentTree.add(
links.createLink(getNameForIndex(unicode),
new StringContent(unicode)));
new StringContent(unicode)));
contentTree.add(Entity.NO_BREAK_SPACE);
}
contentTree.add(new HtmlTree(HtmlTag.BR));
contentTree.add(links.createLink(DocPaths.ALLCLASSES_INDEX,
contents.allClassesLabel));
contents.allClassesLabel));
if (!configuration.packages.isEmpty()) {
contentTree.add(getVerticalSeparator());
contentTree.add(links.createLink(DocPaths.ALLPACKAGES_INDEX,
contents.allPackagesLabel));
contents.allPackagesLabel));
}
if (!configuration.tagSearchIndex.isEmpty()) {
if (!searchItems.get(SearchIndexItem.Category.SEARCH_TAGS).isEmpty()) {
contentTree.add(getVerticalSeparator());
contentTree.add(links.createLink(DocPaths.SYSTEM_PROPERTIES, contents.systemPropertiesLabel));
}

0 comments on commit e8c32cc

Please sign in to comment.