8204303: Add redirect for overview-summary.html
authorjjg
Wed, 06 Jun 2018 15:10:12 -0700
changeset 50434 505d944de3c5
parent 50433 2bafeb7a1f6b
child 50435 d45eb971ad87
8204303: Add redirect for overview-summary.html Reviewed-by: sundar, hannesw
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.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/markup/Head.java
test/langtools/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Wed Jun 06 14:36:48 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java	Wed Jun 06 15:10:12 2018 -0700
@@ -172,8 +172,12 @@
             }
         }
 
-        if (!configuration.frames && !configuration.createoverview) {
-            IndexRedirectWriter.generate(configuration);
+        if (!configuration.frames) {
+            if (configuration.createoverview) {
+                IndexRedirectWriter.generate(configuration, DocPaths.OVERVIEW_SUMMARY, DocPaths.INDEX);
+            } else {
+                IndexRedirectWriter.generate(configuration);
+            }
         }
 
         if (configuration.helpfile.isEmpty() && !configuration.nohelp) {
@@ -201,7 +205,7 @@
         }
     }
 
-    protected void copyJqueryFiles() throws DocletException {
+    private void copyJqueryFiles() throws DocletException {
         List<String> files = Arrays.asList(
                 "jquery-1.12.4.js",
                 "jquery-ui.js",
@@ -245,7 +249,6 @@
     protected void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree)
             throws DocletException {
         List<TypeElement> list = new ArrayList<>(arr);
-        ListIterator<TypeElement> iterator = list.listIterator();
         for (TypeElement klass : list) {
             if (utils.hasHiddenTag(klass) ||
                     !(configuration.isGeneratedDoc(klass) && utils.isIncluded(klass))) {
@@ -274,7 +277,6 @@
                 ModuleIndexFrameWriter.generate(configuration);
             }
             List<ModuleElement> mdles = new ArrayList<>(configuration.modulePackages.keySet());
-            int i = 0;
             for (ModuleElement mdle : mdles) {
                 if (configuration.frames && configuration.modules.size() > 1) {
                     ModulePackageIndexFrameWriter.generate(configuration, mdle);
@@ -283,21 +285,10 @@
                 AbstractBuilder moduleSummaryBuilder =
                         configuration.getBuilderFactory().getModuleSummaryBuilder(mdle);
                 moduleSummaryBuilder.build();
-                i++;
             }
         }
     }
 
-    PackageElement getNamedPackage(List<PackageElement> list, int idx) {
-        if (idx < list.size()) {
-            PackageElement pkg = list.get(idx);
-            if (pkg != null && !pkg.isUnnamed()) {
-                return pkg;
-            }
-        }
-        return null;
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -308,11 +299,10 @@
             PackageIndexFrameWriter.generate(configuration);
         }
         List<PackageElement> pList = new ArrayList<>(packages);
-        for (int i = 0 ; i < pList.size() ; i++) {
+        for (PackageElement pkg : pList) {
             // if -nodeprecated option is set and the package is marked as
             // deprecated, do not generate the package-summary.html, package-frame.html
             // and package-tree.html pages for that package.
-            PackageElement pkg = pList.get(i);
             if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) {
                 if (configuration.frames) {
                     PackageFrameWriter.generate(configuration, pkg);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Wed Jun 06 14:36:48 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Wed Jun 06 15:10:12 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -41,8 +41,8 @@
 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
 
 /**
- * Writes an index.html file that tries to redirect to an alternate page.
- * The redirect uses JavaSCript, if enabled, falling back on
+ * Writes a file that tries to redirect to an alternate page.
+ * The redirect uses JavaScript, if enabled, falling back on
  * {@code <meta http-eqiv=refresh content="0,<uri>">}.
  * If neither are supported/enabled in a browser, the page displays the
  * standard "JavaScipt not enabled" message, and a link to the alternate page.
@@ -51,21 +51,27 @@
 
     public static void generate(HtmlConfiguration configuration)
             throws DocFileIOException {
-        IndexRedirectWriter indexRedirect;
-        DocPath filename = DocPaths.INDEX;
-            indexRedirect = new IndexRedirectWriter(configuration, filename);
-            indexRedirect.generateIndexFile();
+        generate(configuration, DocPaths.INDEX, configuration.topFile);
     }
 
-    IndexRedirectWriter(HtmlConfiguration configuration, DocPath filename) {
+    public static void generate(HtmlConfiguration configuration, DocPath fileName, DocPath target)
+            throws DocFileIOException {
+        IndexRedirectWriter indexRedirect = new IndexRedirectWriter(configuration, fileName, target);
+        indexRedirect.generateIndexFile();
+    }
+
+    private DocPath target;
+
+    private IndexRedirectWriter(HtmlConfiguration configuration, DocPath filename, DocPath target) {
         super(configuration, filename);
+        this.target = target;
     }
 
     /**
      * Generate an index file that redirects to an alternate file.
      * @throws DocFileIOException if there is a problem generating the file
      */
-    void generateIndexFile() throws DocFileIOException {
+    private void generateIndexFile() throws DocFileIOException {
         DocType htmlDocType = DocType.forVersion(configuration.htmlVersion);
         Content htmlComment = contents.newPage;
         Head head = new Head(path, configuration.htmlVersion, configuration.docletVersion)
@@ -77,15 +83,16 @@
                 : resources.getText("doclet.Generated_Docs_Untitled");
 
         head.setTitle(title)
-                .setCharset(configuration.charset);
+                .setCharset(configuration.charset)
+                .setCanonicalLink(target);
 
-        String topFilePath = configuration.topFile.getPath();
+        String targetPath = target.getPath();
         Script script = new Script("window.location.replace(")
-                .appendStringLiteral(topFilePath, '\'')
+                .appendStringLiteral(targetPath, '\'')
                 .append(")");
         HtmlTree metaRefresh = new HtmlTree(HtmlTag.META)
                 .addAttr(HtmlAttr.HTTP_EQUIV, "Refresh")
-                .addAttr(HtmlAttr.CONTENT, "0;" + topFilePath);
+                .addAttr(HtmlAttr.CONTENT, "0;" + targetPath);
         head.addContent(
                 script.asContent(),
                 configuration.isOutputHtml5() ? HtmlTree.NOSCRIPT(metaRefresh) : metaRefresh);
@@ -94,7 +101,7 @@
         bodyContent.addContent(HtmlTree.NOSCRIPT(
                 HtmlTree.P(contents.getContent("doclet.No_Script_Message"))));
 
-        bodyContent.addContent(HtmlTree.P(HtmlTree.A(topFilePath, new StringContent(topFilePath))));
+        bodyContent.addContent(HtmlTree.P(HtmlTree.A(targetPath, new StringContent(targetPath))));
 
         Content body = new HtmlTree(HtmlTag.BODY);
         if (configuration.allowTag(HtmlTag.MAIN)) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Wed Jun 06 14:36:48 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Wed Jun 06 15:10:12 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -67,7 +67,8 @@
     private Script mainBodyScript;
     private final List<Script> scripts;
     private final List<Content> extraContent;
-    boolean addDefaultScript = true;
+    private boolean addDefaultScript = true;
+    private DocPath canonicalLink;
 
     private static final Calendar calendar = new GregorianCalendar(TimeZone.getDefault());
 
@@ -228,6 +229,16 @@
     }
 
     /**
+     * Specifies a value for a
+     * <a href="https://en.wikipedia.org/wiki/Canonical_link_element">canonical link</a>
+     * in the {@code <head>} element.
+     * @param link
+     */
+    public void setCanonicalLink(DocPath link) {
+        this.canonicalLink = link;
+    }
+
+    /**
      * Adds additional content to be included in the HEAD element.
      *
      * @param contents the content
@@ -271,6 +282,13 @@
             tree.addContent(c);
         }
 
+        if (canonicalLink != null) {
+            HtmlTree link = new HtmlTree(HtmlTag.LINK);
+            link.addAttr(HtmlAttr.REL, "canonical");
+            link.addAttr(HtmlAttr.HREF, canonicalLink.getPath());
+            tree.addContent(link);
+        }
+
         addStylesheets(tree);
         addScripts(tree);
 
--- a/test/langtools/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Wed Jun 06 14:36:48 2018 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Wed Jun 06 15:10:12 2018 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8162353 8164747 8173707 8196202
+ * @bug 8162353 8164747 8173707 8196202 8204303
  * @summary javadoc should provide a way to disable use of frames
  * @library /tools/lib ../lib
  * @modules
@@ -269,6 +269,9 @@
                     break;
             }
 
+            out.println("Checker: " + fKind + " " + oKind + " " + hKind
+                + ": frames:" + frames + " overview:" + overview);
+
             checkAllClassesFiles();
             checkFrameFiles();
             checkOverviewSummary();
@@ -380,10 +383,19 @@
         }
 
         private void checkOverviewSummary() {
-            // the overview-summary.html file only appears if
-            // in frames mode and (overview requested or multiple packages)
-            checkFiles(frames && overview,
+            // To accommodate the historical behavior of generating
+            // overview-summary.html in frames mode, the file
+            // will still be generated in no-frames mode,
+            // but will be a redirect to index.html
+            checkFiles(overview,
                     "overview-summary.html");
+            if (overview) {
+                checkOutput("overview-summary.html",  !frames,
+                        "<link rel=\"canonical\" href=\"index.html\">",
+                        "<script type=\"text/javascript\">window.location.replace('index.html')</script>",
+                        "<meta http-equiv=\"Refresh\" content=\"0;index.html\">",
+                        "<p><a href=\"index.html\">index.html</a></p>");
+            }
         }
 
         private void checkWarning() {