8185371: Support for multiple stylesheets in javadoc
authorbpatel
Tue, 14 Nov 2017 13:44:07 -0800
changeset 47748 dfc709c80775
parent 47747 84e7c1515661
child 47749 6cc6869999e2
8185371: Support for multiple stylesheets in javadoc Reviewed-by: jjg, ksrini
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java
test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java
test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-1.css
test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-2.css
test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-3.css
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Tue Nov 14 13:44:07 2017 -0800
@@ -139,7 +139,7 @@
         head.addContent(windowTitle);
         Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, configuration.charset);
         head.addContent(meta);
-        head.addContent(getStyleSheetProperties(configuration));
+        addStyleSheetProperties(configuration, head);
         head.addContent(getFramesJavaScript());
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, body);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java	Tue Nov 14 13:44:07 2017 -0800
@@ -133,6 +133,11 @@
     public String stylesheetfile = "";
 
     /**
+     * Argument for command line option "--add-stylesheet".
+     */
+    public List<String> additionalStylesheets = new ArrayList<>();
+
+    /**
      * Argument for command line option "-Xdocrootparent".
      */
     public String docrootparent = "";
@@ -304,6 +309,22 @@
                 return false;
             }
         }
+        // check if stylesheetfile exists
+        if (!stylesheetfile.isEmpty()) {
+            DocFile stylesheet = DocFile.createFileForInput(this, stylesheetfile);
+            if (!stylesheet.exists()) {
+                reporter.print(ERROR, getText("doclet.File_not_found", stylesheetfile));
+                return false;
+            }
+        }
+        // check if additional stylesheets exists
+        for (String ssheet : additionalStylesheets) {
+            DocFile ssfile = DocFile.createFileForInput(this, ssheet);
+            if (!ssfile.exists()) {
+                reporter.print(ERROR, getText("doclet.File_not_found", ssheet));
+                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
@@ -554,6 +575,13 @@
     public Set<Doclet.Option> getSupportedOptions() {
         Resources resources = getResources();
         Doclet.Option[] options = {
+            new Option(resources, "--add-stylesheet", 1) {
+                @Override
+                public boolean process(String opt, List<String> args) {
+                    additionalStylesheets.add(args.get(0));
+                    return true;
+                }
+            },
             new Option(resources, "-bottom", 1) {
                 @Override
                 public boolean process(String opt,  List<String> args) {
@@ -722,7 +750,7 @@
                     return true;
                 }
             },
-            new Option(resources, "-stylesheetfile", 1) {
+            new Option(resources, "--main-stylesheet -stylesheetfile", 1) {
                 @Override
                 public boolean process(String opt,  List<String> args) {
                     stylesheetfile = args.get(0);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Tue Nov 14 13:44:07 2017 -0800
@@ -125,6 +125,9 @@
         boolean nodeprecated = configuration.nodeprecated;
         performCopy(configuration.helpfile);
         performCopy(configuration.stylesheetfile);
+        for (String stylesheet : configuration.additionalStylesheets) {
+            performCopy(stylesheet);
+        }
         // do early to reduce memory footprint
         if (configuration.classuse) {
             ClassUseWriter.generate(configuration, classtree);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Tue Nov 14 13:44:07 2017 -0800
@@ -2162,6 +2162,7 @@
                 pathToRoot.resolve(stylesheet).getPath(),
                 "Style");
         head.addContent(link);
+        addStylesheets(configuration, head);
         if (configuration.createindex) {
             HtmlTree jq_link = HtmlTree.LINK("stylesheet", "text/css",
                     pathToRoot.resolve(DocPaths.JQUERY_FILES.resolve(DocPaths.JQUERY_STYLESHEET_FILE)).getPath(),
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Tue Nov 14 13:44:07 2017 -0800
@@ -94,7 +94,7 @@
             head.addContent(metaRefresh);
         }
 
-        head.addContent(getStyleSheetProperties(configuration));
+        addStyleSheetProperties(configuration, head);
 
         ContentBuilder bodyContent = new ContentBuilder();
         bodyContent.addContent(HtmlTree.NOSCRIPT(
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Tue Nov 14 13:44:07 2017 -0800
@@ -26,6 +26,7 @@
 package jdk.javadoc.internal.doclets.formats.html;
 
 import java.io.*;
+import java.util.List;
 
 import javax.lang.model.element.Element;
 import javax.lang.model.element.PackageElement;
@@ -210,7 +211,7 @@
         Content head = new HtmlTree(HtmlTag.HEAD);
         head.addContent(HtmlTree.TITLE(new StringContent(
                 configuration.getText("doclet.Window_Source_title"))));
-        head.addContent(getStyleSheetProperties());
+        addStyleSheetProperties(head);
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
                 head, body);
         Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree);
@@ -227,9 +228,9 @@
     /**
      * Returns a link to the stylesheet file.
      *
-     * @return an HtmlTree for the lINK tag which provides the stylesheet location
+     * @param head an HtmlTree to which the stylesheet links will be added
      */
-    public HtmlTree getStyleSheetProperties() {
+    public void addStyleSheetProperties(Content head) {
         String filename = configuration.stylesheetfile;
         DocPath stylesheet;
         if (filename.length() > 0) {
@@ -240,7 +241,21 @@
         }
         DocPath p = relativePath.resolve(stylesheet);
         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", p.getPath(), "Style");
-        return link;
+        head.addContent(link);
+        addStylesheets(head);
+    }
+
+    protected void addStylesheets(Content tree) {
+        List<String> stylesheets = configuration.additionalStylesheets;
+        if (!stylesheets.isEmpty()) {
+            stylesheets.forEach((ssheet) -> {
+                DocFile file = DocFile.createFileForInput(configuration, ssheet);
+                DocPath ssheetPath = DocPath.create(file.getName());
+                HtmlTree slink = HtmlTree.LINK("stylesheet", "text/css", relativePath.resolve(ssheetPath).getPath(),
+                        "Style");
+                tree.addContent(slink);
+            });
+        }
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlDocWriter.java	Tue Nov 14 13:44:07 2017 -0800
@@ -311,9 +311,9 @@
      * Returns a link to the stylesheet file.
      *
      * @param configuration the configuration for this doclet
-     * @return an HtmlTree for the lINK tag which provides the stylesheet location
+     * @param head HtmlTree to which the stylesheet links will be added
      */
-    public HtmlTree getStyleSheetProperties(HtmlConfiguration configuration) {
+    public void addStyleSheetProperties(HtmlConfiguration configuration, Content head) {
         String stylesheetfile = configuration.stylesheetfile;
         DocPath stylesheet;
         if (stylesheetfile.isEmpty()) {
@@ -325,7 +325,21 @@
         HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
                 pathToRoot.resolve(stylesheet).getPath(),
                 "Style");
-        return link;
+        head.addContent(link);
+        addStylesheets(configuration, head);
+    }
+
+    protected void addStylesheets(HtmlConfiguration configuration, Content tree) {
+        List<String> stylesheets = configuration.additionalStylesheets;
+        if (!stylesheets.isEmpty()) {
+            stylesheets.forEach((ssheet) -> {
+                DocFile file = DocFile.createFileForInput(configuration, ssheet);
+                DocPath ssheetPath = DocPath.create(file.getName());
+                HtmlTree slink = HtmlTree.LINK("stylesheet", "text/css", pathToRoot.resolve(ssheetPath).getPath(),
+                        "Style");
+                tree.addContent(slink);
+            });
+        }
     }
 
     protected Comment getGeneratedBy(boolean timestamp) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Tue Nov 14 13:31:43 2017 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties	Tue Nov 14 13:44:07 2017 -0800
@@ -175,6 +175,10 @@
 doclet.Same_element_name_used=Element name or pattern used twice: {0}
 
 # option specifiers
+doclet.usage.add-stylesheet.parameters=\
+    <file>
+doclet.usage.add-stylesheet.description=\
+    Additional stylesheet file for the generated documentation
 doclet.usage.d.parameters=\
     <directory>
 doclet.usage.d.description=\
@@ -329,9 +333,9 @@
 doclet.usage.keywords.description=\
     Include HTML meta tags with package, class and member info
 
-doclet.usage.stylesheetfile.parameters=\
-    <path>
-doclet.usage.stylesheetfile.description=\
+doclet.usage.main-stylesheet.parameters=\
+    <file>
+doclet.usage.main-stylesheet.description=\
     File to change style of the generated documentation
 
 doclet.usage.docencoding.parameters=\
--- a/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testHelpOption/TestHelpOption.java	Tue Nov 14 13:44:07 2017 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug      4934778 4777599 6553182 8146427 8146475 8175055
+ * @bug      4934778 4777599 6553182 8146427 8146475 8175055 8185371
  * @summary  Make sure that -help, -helpfile and -nohelp options work correctly.
  * @author   jamieh
  * @library ../lib
@@ -161,6 +161,7 @@
                 "-sourcetab ",
                 "-keywords ",
                 "-stylesheetfile ",
+                "--add-stylesheet ",
                 "-docencoding ",
                 "-html4 ",
                 "-html5 ",
--- a/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java	Tue Nov 14 13:31:43 2017 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/TestOptions.java	Tue Nov 14 13:44:07 2017 -0800
@@ -23,8 +23,9 @@
 
 /*
  * @test
- * @bug      4749567 8071982 8175200 8186332
- * @summary  Test the output for -header, -footer, -nooverview, -nodeprecatedlist, -nonavbar, -notree, -stylesheetfile options.
+ * @bug      4749567 8071982 8175200 8186332 8185371
+ * @summary  Test the output for -header, -footer, -nooverview, -nodeprecatedlist, -nonavbar, -notree,
+ *           -stylesheetfile, --main-stylesheet, --add-stylesheet options.
  * @author   Bhavesh Patel
  * @library  ../lib
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -118,6 +119,64 @@
     }
 
     @Test
+    void testStylesheetFileAltOption() {
+        javadoc("-d", "out-stylesheet-file",
+                "--main-stylesheet", new File(testSrc, "custom-stylesheet.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("custom-stylesheet.css", true, "Custom javadoc style sheet");
+        checkOutput("pkg/Foo.html", true, "<link rel=\"stylesheet\" type=\"text/css\" "
+                + "href=\"../custom-stylesheet.css\" title=\"Style\">");
+    }
+
+    @Test
+    void testAdditionalStylesheetFile() {
+        javadoc("-d", "out-additional-css",
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-1.css").getAbsolutePath(),
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-2.css").getAbsolutePath(),
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-3.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.OK);
+
+        checkOutput("additional-stylesheet-1.css", true, "Additional javadoc style sheet 1");
+        checkOutput("additional-stylesheet-2.css", true, "Additional javadoc style sheet 2");
+        checkOutput("additional-stylesheet-3.css", true, "Additional javadoc style sheet 3");
+        checkOutput("pkg/Foo.html", true,
+                "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-1.css\" title=\"Style\">\n"
+                + "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-2.css\" title=\"Style\">\n"
+                + "<link rel=\"stylesheet\" type=\"text/css\" href=\"../additional-stylesheet-3.css\" title=\"Style\">");
+    }
+
+    @Test
+    void testInvalidStylesheetFile() {
+        javadoc("-d", "out-invalid-css",
+                "--main-stylesheet", new File(testSrc, "custom-stylesheet-1.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.ERROR);
+
+        checkOutput(Output.OUT, true,
+                "javadoc: error - File not found:",
+                "custom-stylesheet-1.css");
+    }
+
+    @Test
+    void testInvalidAdditionalStylesheetFiles() {
+        javadoc("-d", "out-invalid-additional-css",
+                "--add-stylesheet", new File(testSrc, "additional-stylesheet-4.css").getAbsolutePath(),
+                "-sourcepath", testSrc,
+                "pkg");
+        checkExit(Exit.ERROR);
+
+        checkOutput(Output.OUT, true,
+                "javadoc: error - File not found:",
+                "additional-stylesheet-4.css");
+    }
+
+    @Test
     void testLinkSource() {
         javadoc("-d", "out-9",
                 "-linksource",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-1.css	Tue Nov 14 13:44:07 2017 -0800
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 1 */
+
+body {
+    background-color:#f8f8ff;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-2.css	Tue Nov 14 13:44:07 2017 -0800
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 2 */
+
+.subNav {
+    background-color:#fafad2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testOptions/additional-stylesheet-3.css	Tue Nov 14 13:44:07 2017 -0800
@@ -0,0 +1,5 @@
+/* Additional javadoc style sheet 3 */
+
+a:link, a:visited {
+    color:#8b0000;
+}