Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8247994: Localize javadoc search
Reviewed-by: hannesw, ihse
  • Loading branch information
jonathan-gibbons committed Dec 17, 2020
1 parent 47c180d commit 30ca0a5d4b9f0d634c6afc2f5300c025a7f4e1b8
@@ -74,7 +74,7 @@ define SetupInterimModule
EXCLUDE_FILES := $(TOPDIR)/src/$1/share/classes/module-info.java \
Standard.java, \
EXTRA_FILES := $(BUILDTOOLS_OUTPUTDIR)/gensrc/$1.interim/module-info.java, \
COPY := .gif .png .xml .css .js .txt javax.tools.JavaCompilerTool, \
COPY := .gif .png .xml .css .js .js.template .txt javax.tools.JavaCompilerTool, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_langtools_modules/$1.interim, \
DISABLED_WARNINGS := module options, \
JAVAC_FLAGS := \
@@ -339,7 +339,7 @@ jdk.dynalink_CLEAN += .properties

################################################################################

jdk.javadoc_COPY += .xml .css .js .png .txt
jdk.javadoc_COPY += .xml .css .js .js.template .png .txt

################################################################################

@@ -32,7 +32,6 @@
import javax.lang.model.element.TypeElement;

import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import jdk.javadoc.internal.doclets.toolkit.AbstractDoclet;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
@@ -216,7 +215,7 @@ protected void generateOtherFiles(ClassTree classtree)
f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true);
if (options.createIndex()) {
f = DocFile.createFileForOutput(configuration, DocPaths.SEARCH_JS);
f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.SEARCH_JS), true, true);
f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.SEARCH_JS_TEMPLATE), configuration.docResources);

f = DocFile.createFileForOutput(configuration, DocPaths.RESOURCES.resolve(DocPaths.GLASS_IMG));
f.copyResource(DOCLET_RESOURCES.resolve(DocPaths.GLASS_IMG), true, false);
@@ -23,13 +23,13 @@
* questions.
*/

var noResult = {l: "No results found"};
var loading = {l: "Loading search index..."};
var catModules = "Modules";
var catPackages = "Packages";
var catTypes = "Types";
var catMembers = "Members";
var catSearchTags = "SearchTags";
var noResult = {l: "##REPLACE:doclet.search.no_results##"};
var loading = {l: "##REPLACE:doclet.search.loading##"};
var catModules = "##REPLACE:doclet.search.modules##";
var catPackages = "##REPLACE:doclet.search.packages##";
var catTypes = "##REPLACE:doclet.search.types##";
var catMembers = "##REPLACE:doclet.search.members##";
var catSearchTags = "##REPLACE:doclet.search.search_tags##";
var highlight = "<span class=\"result-highlight\">$&</span>";
var searchPattern = "";
var fallbackPattern = "";
@@ -333,3 +333,11 @@ doclet.record_field_doc.fullbody=\
doclet.platform.docs.old=https://docs.oracle.com/javase/{0}/docs/api/
doclet.platform.docs.new=https://docs.oracle.com/en/java/javase/{0}/docs/api/
doclet.platform.docs.ea=https://download.java.net/java/early_access/jdk{0}/docs/api/

doclet.search.no_results=No results found
doclet.search.loading=Loading search index...
doclet.search.modules=Modules
doclet.search.packages=Packages
doclet.search.types=Types
doclet.search.members=Members
doclet.search.search_tags=Search Tags
@@ -32,12 +32,17 @@
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.MissingResourceException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.tools.DocumentationTool;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;

import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.Resources;

/**
* Abstraction for handling files, which may be specified directly
@@ -175,10 +180,28 @@ public void copyFile(DocFile fromFile) throws DocFileIOException {
* @throws ResourceIOException if there is a problem while reading the resource
*/
public void copyResource(DocPath resource, boolean overwrite, boolean replaceNewLine)
throws DocFileIOException, ResourceIOException {
throws DocFileIOException, ResourceIOException {
if (exists() && !overwrite)
return;

copyResource(resource, replaceNewLine, null);
}

/**
* Copy the contents of a resource file to this file.
*
* @param resource the path of the resource, relative to the package of this class
* @param resources if not {@code null}, substitute occurrences of {@code ##REPLACE:key##}
*
* @throws DocFileIOException if there is a problem while writing the copy
* @throws ResourceIOException if there is a problem while reading the resource
*/
public void copyResource(DocPath resource, Resources resources) throws DocFileIOException, ResourceIOException {
copyResource(resource, true, resources);
}

private void copyResource(DocPath resource, boolean replaceNewLine, Resources resources)
throws DocFileIOException, ResourceIOException {
try {
InputStream in = BaseConfiguration.class.getResourceAsStream(resource.getPath());
if (in == null)
@@ -190,7 +213,7 @@ public void copyResource(DocPath resource, boolean overwrite, boolean replaceNew
try (Writer writer = openWriter()) {
String line;
while ((line = readResourceLine(resource, reader)) != null) {
write(this, writer, line);
write(this, writer, resources == null ? line : localize(line, resources));
write(this, writer, DocletConstants.NL);
}
} catch (IOException e) {
@@ -216,6 +239,32 @@ public void copyResource(DocPath resource, boolean overwrite, boolean replaceNew
}
}

private static final Pattern replacePtn = Pattern.compile("##REPLACE:(?<key>[A-Za-z0-9._]+)##");

private String localize(String line, Resources resources) {
Matcher m = replacePtn.matcher(line);
StringBuilder sb = null;
int start = 0;
while (m.find()) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append(line, start, m.start());
try {
sb.append(resources.getText(m.group("key")));
} catch (MissingResourceException e) {
sb.append(m.group());
}
start = m.end();
}
if (sb == null) {
return line;
} else {
sb.append(line.substring(start));
return sb.toString();
}
}

/** Return true if the file can be read. */
public abstract boolean canRead();

@@ -279,11 +328,12 @@ public void copyResource(DocPath resource, boolean overwrite, boolean replaceNew

/**
* Reads from an input stream opened from a given file into a given buffer.
* If an IOException occurs, it is wrapped in a DocFileIOException.
* If an {@code IOException} occurs, it is wrapped in a {@code DocFileIOException}.
*
* @param inFile the file for the stream
* @param input the stream
* @param buf the buffer
* @param input the stream
* @param buf the buffer
*
* @return the number of bytes read, or -1 if at end of file
* @throws DocFileIOException if an exception occurred while reading the stream
*/
@@ -297,11 +347,12 @@ private static int read(DocFile inFile, InputStream input, byte[] buf) throws Do

/**
* Writes to an output stream for a given file from a given buffer.
* If an IOException occurs, it is wrapped in a DocFileIOException.
* If an {@code IOException} occurs, it is wrapped in a {@code DocFileIOException}.
*
* @param outFile the file for the stream
* @param out the stream
* @param buf the buffer
* @param out the stream
* @param buf the buffer
*
* @throws DocFileIOException if an exception occurred while writing the stream
*/
private static void write(DocFile outFile, OutputStream out, byte[] buf, int len) throws DocFileIOException {
@@ -314,11 +365,12 @@ private static void write(DocFile outFile, OutputStream out, byte[] buf, int len

/**
* Writes text to an output stream for a given file from a given buffer.
* If an IOException occurs, it is wrapped in a DocFileIOException.
* If an {@code IOException} occurs, it is wrapped in a {@code DocFileIOException}.
*
* @param outFile the file for the stream
* @param out the stream
* @param text the text to be written
* @param out the stream
* @param text the text to be written
*
* @throws DocFileIOException if an exception occurred while writing the stream
*/
private static void write(DocFile outFile, Writer out, String text) throws DocFileIOException {
@@ -331,28 +383,30 @@ private static void write(DocFile outFile, Writer out, String text) throws DocFi

/**
* Reads from an input stream opened from a given resource into a given buffer.
* If an IOException occurs, it is wrapped in a ResourceIOException.
* If an {@code IOException} occurs, it is wrapped in a {@code ResourceIOException}.
*
* @param docPath the resource for the stream
* @param in the stream
* @param buf the buffer
*
* @param resource the resource for the stream
* @param in the stream
* @param buf the buffer
* @return the number of bytes read, or -1 if at end of file
* @throws ResourceIOException if an exception occurred while reading the stream
*/
private static int readResource(DocPath resource, InputStream in, byte[] buf) throws ResourceIOException {
private static int readResource(DocPath docPath, InputStream in, byte[] buf) throws ResourceIOException {
try {
return in.read(buf);
} catch (IOException e) {
throw new ResourceIOException(resource, e);
throw new ResourceIOException(docPath, e);
}
}

/**
* Reads a line of characters from an input stream opened from a given resource.
* If an IOException occurs, it is wrapped in a ResourceIOException.
* If an {@code IOException} occurs, it is wrapped in a {@code ResourceIOException}.
*
* @param docPath the resource for the stream
* @param in the stream
*
* @param resource the resource for the stream
* @param in the stream
* @return the line of text, or {@code null} if at end of stream
* @throws ResourceIOException if an exception occurred while reading the stream
*/
@@ -275,6 +275,9 @@ private DocPath createModulePath(String moduleName, String path) {
/** The name of the search javascript file. */
public static final DocPath SEARCH_JS = DocPath.create("search.js");

/** The name of the template for the search javascript file. */
public static final DocPath SEARCH_JS_TEMPLATE = DocPath.create("search.js.template");

/** The name of the file for the serialized form info. */
public static final DocPath SERIALIZED_FORM = DocPath.create("serialized-form.html");

@@ -25,7 +25,7 @@
* @test
* @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881
* 8181622 8182263 8074407 8187521 8198522 8182765 8199278 8196201 8196202
* 8184205 8214468 8222548 8223378 8234746 8241219 8254627
* 8184205 8214468 8222548 8223378 8234746 8241219 8254627 8247994
* @summary Test the search feature of javadoc.
* @library ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -711,6 +711,10 @@ void checkJqueryAndImageFiles(boolean expectedOutput) {
}

void checkSearchJS() {
// ensure all resource keys were resolved
checkOutput("search.js", false,
"##REPLACE:");

checkOutput("search.js", true,
"function searchIndexWithMatcher(indexArray, matcher, category, nameFunc) {",
"""
@@ -23,7 +23,7 @@

/*
* @test
* @bug 8000612 8254627
* @bug 8000612 8254627 8247994
* @summary need test program to validate javadoc resource bundles
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.resources:open
@@ -34,6 +34,8 @@

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.tools.*;
import com.sun.tools.classfile.*;

@@ -200,6 +202,17 @@ void findMissingKeys(Set<String> codeKeys, Set<String> resourceKeys) {
}
}

// special handling for strings in search.js.template
FileObject fo = fm.getFileForInput(javadocLoc,
"jdk.javadoc.internal.doclets.formats.html",
"resources/search.js.template");
CharSequence search_js = fo.getCharContent(true);
Pattern p = Pattern.compile("##REPLACE:(?<key>[A-Za-z0-9._]+)##");
Matcher m = p.matcher(search_js);
while (m.find()) {
results.add(m.group("key"));
}

// special handling for code strings synthesized in
// jdk.javadoc.internal.doclets.toolkit.util.Utils.getTypeName
String[] extras = {

1 comment on commit 30ca0a5

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 30ca0a5 Dec 17, 2020

Please sign in to comment.