8275786: New javadoc option to add script files to generated documentation

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2021-11-11 09:13:49 +00:00
parent 7a140af253
commit 9862cd07c1
12 changed files with 130 additions and 29 deletions

View File

@ -379,6 +379,13 @@ public class HtmlConfiguration extends BaseConfiguration {
.collect(Collectors.toCollection(ArrayList::new));
}
public List<DocPath> getAdditionalScripts() {
return options.additionalScripts().stream()
.map(sf -> DocFile.createFileForInput(this, sf))
.map(file -> DocPath.create(file.getName()))
.collect(Collectors.toCollection(ArrayList::new));
}
@Override
public JavaFileManager getFileManager() {
return docEnv.getJavaFileManager();

View File

@ -26,8 +26,6 @@
package jdk.javadoc.internal.doclets.formats.html;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
@ -215,7 +213,7 @@ public class HtmlDoclet extends AbstractDoclet {
super.generateOtherFiles(classtree);
HtmlOptions options = configuration.getOptions();
if (options.linkSource()) {
SourceToHTMLConverter.convertRoot(configuration,DocPaths.SOURCE_OUTPUT);
SourceToHTMLConverter.convertRoot(configuration, DocPaths.SOURCE_OUTPUT);
}
// Modules with no documented classes may be specified on the
// command line to specify a service provider, allow these.
@ -225,10 +223,13 @@ public class HtmlDoclet extends AbstractDoclet {
return;
}
boolean nodeprecated = options.noDeprecated();
performCopy(options.helpFile());
performCopy(options.stylesheetFile());
performCopy(options.helpFile(), DocPath.empty);
performCopy(options.stylesheetFile(), DocPath.empty);
for (String stylesheet : options.additionalStylesheets()) {
performCopy(stylesheet);
performCopy(stylesheet, DocPath.empty);
}
for (String script : options.additionalScripts()) {
performCopy(script, DocPaths.SCRIPT_DIR);
}
// do early to reduce memory footprint
if (options.classUse()) {
@ -329,7 +330,7 @@ public class HtmlDoclet extends AbstractDoclet {
"images/ui-bg_glass_75_e6e6e6_1x400.png");
DocFile f;
for (String file : files) {
DocPath filePath = DocPaths.JQUERY_FILES.resolve(file);
DocPath filePath = DocPaths.SCRIPT_DIR.resolve(file);
f = DocFile.createFileForOutput(configuration, filePath);
f.copyResource(DOCLET_RESOURCES.resolve(filePath), true, false);
}
@ -428,18 +429,20 @@ public class HtmlDoclet extends AbstractDoclet {
return configuration.getOptions().getSupportedOptions();
}
private void performCopy(String filename) throws DocFileIOException {
if (filename.isEmpty())
private void performCopy(String filename, DocPath targetPath) throws DocFileIOException {
if (filename.isEmpty()) {
return;
}
DocFile fromfile = DocFile.createFileForInput(configuration, filename);
DocPath path = DocPath.create(fromfile.getName());
DocPath path = targetPath.resolve(fromfile.getName());
DocFile toFile = DocFile.createFileForOutput(configuration, path);
if (toFile.isSameFile(fromfile))
if (toFile.isSameFile(fromfile)) {
return;
}
messages.notice("doclet.Copying_File_0_To_File_1",
fromfile.toString(), path.getPath());
fromfile.getPath(), path.getPath());
toFile.copyFile(fromfile);
}
}

View File

@ -459,6 +459,7 @@ public class HtmlDocletWriter {
.setCharset(options.charset())
.addKeywords(metakeywords)
.setStylesheets(configuration.getMainStylesheet(), additionalStylesheets)
.setAdditionalScripts(configuration.getAdditionalScripts())
.setIndex(options.createIndex(), mainBodyScript)
.addContent(extraHeadContent);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, 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
@ -59,6 +59,11 @@ public class HtmlOptions extends BaseOptions {
*/
private List<String> additionalStylesheets = new ArrayList<>();
/**
* Argument for command-line option {@code --add-script}.
*/
private List<String> additionalScripts = new ArrayList<>();
/**
* Argument for command-line option {@code -bottom}.
*/
@ -199,6 +204,14 @@ public class HtmlOptions extends BaseOptions {
Resources resources = messages.getResources();
List<Option> options = List.of(
new Option(resources, "--add-script", 1) {
@Override
public boolean process(String opt, List<String> args) {
additionalScripts.add(args.get(0));
return true;
}
},
new Option(resources, "--add-stylesheet", 1) {
@Override
public boolean process(String opt, List<String> args) {
@ -500,7 +513,14 @@ public class HtmlOptions extends BaseOptions {
return false;
}
}
// check if additional scripts exists
for (String script : additionalScripts) {
DocFile sfile = DocFile.createFileForInput(config, script);
if (!sfile.exists()) {
messages.error("doclet.File_not_found", script);
return false;
}
}
// In a more object-oriented world, this would be done by methods on the Option objects.
// Note that -windowtitle silently removes any and all HTML elements, and so does not need
// to be handled here.
@ -514,6 +534,13 @@ public class HtmlOptions extends BaseOptions {
return true;
}
/**
* Argument for command-line option {@code --add-script}.
*/
List<String> additionalScripts() {
return additionalScripts;
}
/**
* Argument for command-line option {@code --add-stylesheet}.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@ -63,6 +63,8 @@ public class Head extends Content {
private boolean index;
private Script mainBodyScript;
private final List<Script> scripts;
// Scripts added via --add-script option
private List<DocPath> additionalScripts = Collections.emptyList();
private final List<Content> extraContent;
private boolean addDefaultScript = true;
private DocPath canonicalLink;
@ -168,6 +170,19 @@ public class Head extends Content {
return this;
}
/**
* Sets the list of additional script files to be added to the HEAD element.
* The path for the script files must be relative to the root of the generated
* documentation hierarchy.
*
* @param scripts the list of additional script files
* @return this object
*/
public Head setAdditionalScripts(List<DocPath> scripts) {
this.additionalScripts = scripts;
return this;
}
/**
* Sets whether or not to include the supporting scripts and stylesheets for the
* "search" feature.
@ -315,7 +330,7 @@ public class Head extends Content {
if (index) {
// The order of the addStylesheet(...) calls is important
addStylesheet(tree, DocPaths.JQUERY_FILES.resolve(DocPaths.JQUERY_UI_CSS));
addStylesheet(tree, DocPaths.SCRIPT_DIR.resolve(DocPaths.JQUERY_UI_CSS));
addStylesheet(tree, DocPaths.JQUERY_OVERRIDES_CSS);
}
}
@ -337,16 +352,19 @@ public class Head extends Content {
.append(";\n")
.append("loadScripts(document, 'script');");
}
addJQueryFile(tree, DocPaths.JQUERY_JS);
addJQueryFile(tree, DocPaths.JQUERY_UI_JS);
addScriptElement(tree, DocPaths.JQUERY_JS);
addScriptElement(tree, DocPaths.JQUERY_UI_JS);
}
for (DocPath path : additionalScripts) {
addScriptElement(tree, path);
}
for (Script script : scripts) {
tree.add(script.asContent());
}
}
private void addJQueryFile(HtmlTree tree, DocPath filePath) {
DocPath jqueryFile = pathToRoot.resolve(DocPaths.JQUERY_FILES.resolve(filePath));
tree.add(HtmlTree.SCRIPT(jqueryFile.getPath()));
private void addScriptElement(HtmlTree tree, DocPath filePath) {
DocPath scriptFile = pathToRoot.resolve(DocPaths.SCRIPT_DIR).resolve(filePath);
tree.add(HtmlTree.SCRIPT(scriptFile.getPath()));
}
}

View File

@ -381,10 +381,14 @@ doclet.Error_copying_legal_notices=Error while copying legal notices: {0}
doclet.Error_invalid_path_for_legal_notices=Invalid path ''{0}'' for legal notices: {1}
# option specifiers
doclet.usage.add-script.parameters=\
<file>
doclet.usage.add-script.description=\
Add a script file to the generated documentation
doclet.usage.add-stylesheet.parameters=\
<file>
doclet.usage.add-stylesheet.description=\
Additional stylesheet file for the generated documentation
Add a stylesheet file to the generated documentation
doclet.usage.d.parameters=\
<directory>
doclet.usage.d.description=\

View File

@ -103,9 +103,6 @@ public class DocPaths {
/** The name of the stylesheet file overriding jQuery UI stylesheet. */
public static final DocPath JQUERY_OVERRIDES_CSS = DocPath.create("jquery-ui.overrides.css");
/** The name of the directory for the jQuery files. */
public static final DocPath JQUERY_FILES = DocPath.create("script-dir");
/** The name of the default jQuery javascript file. */
public static final DocPath JQUERY_JS = DocPath.create("jquery-3.5.1.min.js");
@ -124,6 +121,9 @@ public class DocPaths {
/** The name of the module search index js file. */
public static final DocPath MODULE_SEARCH_INDEX_JS = DocPath.create("module-search-index.js");
/** The name of the file for new elements. */
public static final DocPath NEW_LIST = DocPath.create("new-list.html");
/** The name of the file for the overview summary. */
public static final DocPath OVERVIEW_SUMMARY = DocPath.create("overview-summary.html");
@ -148,8 +148,8 @@ public class DocPaths {
/** The name of the file for preview elements. */
public static final DocPath PREVIEW_LIST = DocPath.create("preview-list.html");
/** The name of the file for new elements. */
public static final DocPath NEW_LIST = DocPath.create("new-list.html");
/** The name of the directory for the script files. */
public static final DocPath SCRIPT_DIR = DocPath.create("script-dir");
/** The name of the file for all system properties. */
public static final DocPath SYSTEM_PROPERTIES = DocPath.create("system-properties.html");

View File

@ -165,6 +165,7 @@ public class TestHelpOption extends JavadocTester {
"-keywords ",
"-stylesheetfile ",
"--add-stylesheet ",
"--add-script",
"-docencoding ",
"-html5 ",
"-top ",

View File

@ -24,8 +24,10 @@
/*
* @test
* @bug 4749567 8071982 8175200 8186332 8185371 8182765 8217034 8261976 8261976
* @summary Test the output for -header, -footer, -nooverview, -nodeprecatedlist, -nonavbar, -notree,
* -stylesheetfile, --main-stylesheet, --add-stylesheet options.
* 8275786
* @summary Test the output for -header, -footer, -nooverview, -nodeprecatedlist,
* -nonavbar, -notree, -stylesheetfile, --main-stylesheet, --add-stylesheet,
* --add-script options.
* @library ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @build javadoc.tester.*
@ -178,6 +180,37 @@ public class TestOptions extends JavadocTester {
"additional-stylesheet-4.css");
}
@Test
public void testAdditionalScriptFile() {
javadoc("-d", "out-additional-script",
"--add-script", new File(testSrc, "additional-script-1.js").getAbsolutePath(),
"--add-script", new File(testSrc, "additional-script-2.js").getAbsolutePath(),
"-sourcepath", testSrc,
"pkg");
checkExit(Exit.OK);
checkOutput("script-dir/additional-script-1.js", true, "Additional script file 1");
checkOutput("script-dir/additional-script-2.js", true, "Additional script file 2");
checkOutput("pkg/Foo.html", true,
"""
<script type="text/javascript" src="../script-dir/additional-script-1.js"></script>
<script type="text/javascript" src="../script-dir/additional-script-2.js"></script>
""");
}
@Test
public void testInvalidAdditionalScriptFile() {
javadoc("-d", "out-invalid-additional-script",
"--add-script", new File(testSrc, "additional-script-3.js").getAbsolutePath(),
"-sourcepath", testSrc,
"pkg");
checkExit(Exit.ERROR);
checkOutput(Output.OUT, true,
"error: File not found:",
"additional-script-3.js");
}
@Test
public void testLinkSource() {
javadoc("-d", "out-9",

View File

@ -0,0 +1,3 @@
// Additional script file 1
console.log("hello world");

View File

@ -0,0 +1,3 @@
// Additional script file 2
console.log("goodbye");

View File

@ -62,6 +62,7 @@ public class CheckManPageOptions {
// FIXME: JDK-8274295, JDK-8266666
List<String> MISSING_IN_MAN_PAGE = List.of(
"--add-script",
"--legal-notices",
"--link-platform-properties",
"--no-platform-links",