changeset 55044:d001808c57e8

8218998: Add metadata to generated API documentation files Reviewed-by: hannesw
author jjg
date Wed, 20 Feb 2019 16:15:02 -0800
parents 6c13f5a67766
children 81a9748bc86c
files src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractPackageIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.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/ModuleFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.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/SplitIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java test/langtools/jdk/javadoc/doclet/testMetadata/TestMetadata.java
diffstat 33 files changed, 565 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -33,7 +33,6 @@
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.PackageElement;
 
-import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@@ -124,11 +123,13 @@
      * methods from the sub-class in order to generate Frame or Non
      * Frame format.
      *
-     * @param title the title of the window.
+     * @param title the title of the window
+     * @param description the content for the description META tag
      * @param includeScript boolean set true if windowtitle script is to be included
      * @throws DocFileIOException if there is a problem building the module index file
      */
-    protected void buildModuleIndexFile(String title, boolean includeScript) throws DocFileIOException {
+    protected void buildModuleIndexFile(String title, String description, boolean includeScript)
+            throws DocFileIOException {
         String windowOverview = resources.getText(title);
         Content body = getBody(includeScript, getWindowTitle(windowOverview));
         Content header = HtmlTree.HEADER();
@@ -142,8 +143,11 @@
         body.addContent(header);
         body.addContent(main);
         body.addContent(footer);
-        printHtmlDocument(configuration.metakeywords.getOverviewMetaKeywords(title,
-                configuration.doctitle), includeScript, body);
+        printHtmlDocument(
+                configuration.metakeywords.getOverviewMetaKeywords(title, configuration.doctitle),
+                description,
+                includeScript,
+                body);
     }
 
     /**
@@ -152,11 +156,12 @@
      * Frame format.
      *
      * @param title the title of the window.
+     * @param description the content for the description META tag
      * @param includeScript boolean set true if windowtitle script is to be included
      * @param mdle the name of the module being documented
      * @throws DocFileIOException if there is an exception building the module packages index file
      */
-    protected void buildModulePackagesIndexFile(String title,
+    protected void buildModulePackagesIndexFile(String title, String description,
             boolean includeScript, ModuleElement mdle) throws DocFileIOException {
         String windowOverview = resources.getText(title);
         Content body = getBody(includeScript, getWindowTitle(windowOverview));
@@ -171,8 +176,11 @@
         body.addContent(header);
         body.addContent(main);
         body.addContent(footer);
-        printHtmlDocument(configuration.metakeywords.getOverviewMetaKeywords(title,
-                configuration.doctitle), includeScript, body);
+        printHtmlDocument(
+                configuration.metakeywords.getOverviewMetaKeywords(title, configuration.doctitle),
+                description,
+                includeScript,
+                body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractPackageIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractPackageIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -29,7 +29,6 @@
 
 import javax.lang.model.element.PackageElement;
 
-import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@@ -109,11 +108,13 @@
      * methods from the sub-class in order to generate Frame or Non
      * Frame format.
      *
-     * @param title the title of the window.
+     * @param title the title of the window
+     * @param description the content for the description META tag
      * @param includeScript boolean set true if windowtitle script is to be included
      * @throws DocFileIOException if there is a problem building the package index file
      */
-    protected void buildPackageIndexFile(String title, boolean includeScript) throws DocFileIOException {
+    protected void buildPackageIndexFile(String title, String description, boolean includeScript)
+            throws DocFileIOException {
         String windowOverview = resources.getText(title);
         Content body = getBody(includeScript, getWindowTitle(windowOverview));
         Content header = HtmlTree.HEADER();
@@ -127,8 +128,9 @@
         body.addContent(header);
         body.addContent(main);
         body.addContent(footer);
-        printHtmlDocument(configuration.metakeywords.getOverviewMetaKeywords(title,
-                configuration.doctitle), includeScript, body);
+        printHtmlDocument(
+                configuration.metakeywords.getOverviewMetaKeywords(title, configuration.doctitle),
+                description, includeScript, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -29,7 +29,6 @@
 import javax.lang.model.element.Element;
 import javax.lang.model.element.TypeElement;
 
-import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@@ -122,7 +121,7 @@
         HtmlTree div = HtmlTree.DIV(HtmlStyle.indexContainer, ul);
         htmlTree.addContent(div);
         body.addContent(htmlTree);
-        printHtmlDocument(null, false, body);
+        printHtmlDocument(null, "all classes (frame)", false, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -117,7 +117,7 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         bodyTree.addContent(footer);
-        printHtmlDocument(null, true, bodyTree);
+        printHtmlDocument(null, "class index", true, bodyTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -105,7 +105,7 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         bodyTree.addContent(footer);
-        printHtmlDocument(null, true, bodyTree);
+        printHtmlDocument(null, "package index", true, bodyTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -152,8 +152,11 @@
      */
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
+        String description = getDescription("declaration", annotationType);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(annotationType),
-                true, contentTree);
+                description,
+                true,
+                contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -27,7 +27,6 @@
 
 import jdk.javadoc.internal.doclets.formats.html.markup.Table;
 
-import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -241,7 +240,8 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         body.addContent(footer);
-        printHtmlDocument(null, true, body);
+        String description = getDescription("use", typeElement);
+        printHtmlDocument(null, description, true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -177,8 +177,11 @@
      */
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
+        String description = getDescription("declaration", typeElement);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(typeElement),
-                true, contentTree);
+                description,
+                true,
+                contentTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -328,6 +328,6 @@
      */
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
-        printHtmlDocument(null, true, contentTree);
+        printHtmlDocument(null, "summary of constants", true, contentTree);
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -308,7 +308,8 @@
         htmlTree.addContent(navBar.getContent(false));
         addBottom(htmlTree);
         body.addContent(htmlTree);
-        printHtmlDocument(null, true, body);
+        String description = "deprecated elements";
+        printHtmlDocument(null, description, true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -197,7 +197,7 @@
         footer.addContent(navBar.getContent(false));
         docletWriter.addBottom(footer);
         htmlContent.addContent(footer);
-        docletWriter.printHtmlDocument(Collections.emptyList(), false, localTagsContent, htmlContent);
+        docletWriter.printHtmlDocument(Collections.emptyList(), null, false, localTagsContent, htmlContent);
     }
 
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -128,6 +128,8 @@
         Head head = new Head(path, configuration.docletVersion)
                 .setTimestamp(!configuration.notimestamp)
                 .setTitle(title)
+                .setDescription("frames")
+                .setGenerator(getGenerator(getClass()))
                 .setCharset(configuration.charset)
                 .setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets())
                 .addDefaultScript(false)
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -100,7 +100,7 @@
         htmlTree.addContent(navBar.getContent(false));
         addBottom(htmlTree);
         body.addContent(htmlTree);
-        printHtmlDocument(null, true, body);
+        printHtmlDocument(null, "help", true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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,6 +41,7 @@
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.Name;
 import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.QualifiedNameable;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.DeclaredType;
@@ -421,14 +422,18 @@
      * @param metakeywords Array of String keywords for META tag. Each element
      *                     of the array is assigned to a separate META tag.
      *                     Pass in null for no array
+     * @param description the content for the description META tag.
      * @param includeScript true if printing windowtitle script
      *                      false for files that appear in the left-hand frames
      * @param body the body htmltree to be included in the document
      * @throws DocFileIOException if there is a problem writing the file
      */
-    public void printHtmlDocument(List<String> metakeywords, boolean includeScript,
-                                  Content body) throws DocFileIOException {
-        printHtmlDocument(metakeywords, includeScript, new ContentBuilder(), body);
+    public void printHtmlDocument(List<String> metakeywords,
+                                  String description,
+                                  boolean includeScript,
+                                  Content body)
+            throws DocFileIOException {
+        printHtmlDocument(metakeywords, description, includeScript, new ContentBuilder(), body);
     }
 
     /**
@@ -437,24 +442,31 @@
      * @param metakeywords Array of String keywords for META tag. Each element
      *                     of the array is assigned to a separate META tag.
      *                     Pass in null for no array
+     * @param description the content for the description META tag.
      * @param includeScript true if printing windowtitle script
      *                      false for files that appear in the left-hand frames
-     * @param extraContent any additional content to be included in the HEAD element
+     * @param extraHeadContent any additional content to be included in the HEAD element
      * @param body the body htmltree to be included in the document
      * @throws DocFileIOException if there is a problem writing the file
      */
-    public void printHtmlDocument(List<String> metakeywords, boolean includeScript, Content extraContent,
-                                  Content body) throws DocFileIOException {
+    public void printHtmlDocument(List<String> metakeywords,
+                                  String description,
+                                  boolean includeScript,
+                                  Content extraHeadContent,
+                                  Content body)
+            throws DocFileIOException {
         Content htmlComment = contents.newPage;
         Head head = new Head(path, configuration.docletVersion)
                 .setTimestamp(!configuration.notimestamp)
+                .setDescription(description)
+                .setGenerator(getGenerator(getClass()))
                 .setTitle(winTitle)
                 .setCharset(configuration.charset)
                 .addKeywords(metakeywords)
                 .setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets())
                 .setUseModuleDirectories(configuration.useModuleDirectories)
                 .setIndex(configuration.createindex, mainBodyScript)
-                .addContent(extraContent);
+                .addContent(extraHeadContent);
 
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), head.toContent(), body);
         HtmlDocument htmlDocument = new HtmlDocument(htmlComment, htmlTree);
@@ -2111,6 +2123,55 @@
     }
 
     /**
+     * Generates a string for use in a description meta element,
+     * based on an element and its enclosing elements
+     * @param prefix a prefix for the string
+     * @param elem the element
+     * @return the description
+     */
+    static String getDescription(String prefix, Element elem) {
+        LinkedList<Element> chain = new LinkedList<>();
+        for (Element e = elem; e != null; e = e.getEnclosingElement()) {
+            // ignore unnamed enclosing elements
+            if (e.getSimpleName().length() == 0 && e != elem) {
+                break;
+            }
+            chain.addFirst(e);
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Element e: chain) {
+            CharSequence name;
+            switch (e.getKind()) {
+                case MODULE:
+                case PACKAGE:
+                    name = ((QualifiedNameable) e).getQualifiedName();
+                    if (name.length() == 0) {
+                        name = "<unnamed>";
+                    }
+                    break;
+
+                default:
+                    name = e.getSimpleName();
+                    break;
+            }
+
+            if (sb.length() == 0) {
+                sb.append(prefix).append(": ");
+            } else {
+                sb.append(", ");
+            }
+            sb.append(e.getKind().toString().toLowerCase(Locale.US).replace("_", " "))
+                    .append(": ")
+                    .append(name);
+        }
+        return sb.toString();
+    }
+
+    static String getGenerator(Class<?> clazz) {
+        return "javadoc/" + clazz.getSimpleName();
+    }
+
+    /**
      * Returns an HtmlTree for the SCRIPT tag.
      *
      * @return an HtmlTree for the SCRIPT tag
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -79,6 +79,8 @@
         Content htmlComment = contents.newPage;
         Head head = new Head(path, configuration.docletVersion)
                 .setTimestamp(true)
+                .setDescription("index redirect")
+                .setGenerator(getGenerator(getClass()))
                 .setStylesheets(configuration.getMainStylesheet(), Collections.emptyList()) // avoid reference to default stylesheet
                 .addDefaultScript(false);
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -36,7 +36,6 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
-import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@@ -111,7 +110,10 @@
         htmlTree.addContent(div);
         body.addContent(htmlTree);
         mdlgen.printHtmlDocument(
-                configuration.metakeywords.getMetaKeywordsForModule(moduleElement), false, body);
+                configuration.metakeywords.getMetaKeywordsForModule(moduleElement),
+                "module summary (frame)",
+                false,
+                body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -77,7 +77,7 @@
     public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
         DocPath filename = DocPaths.MODULE_OVERVIEW_FRAME;
         ModuleIndexFrameWriter modulegen = new ModuleIndexFrameWriter(configuration, filename);
-        modulegen.buildModuleIndexFile("doclet.Window_Overview", false);
+        modulegen.buildModuleIndexFile("doclet.Window_Overview", "module overview (frame)", false);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -74,7 +74,7 @@
     public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
         DocPath filename = DocPaths.overviewSummary(configuration.frames);
         ModuleIndexWriter mdlgen = new ModuleIndexWriter(configuration, filename);
-        mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", true);
+        mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", "module index", true);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -77,7 +77,10 @@
     public static void generate(HtmlConfiguration configuration, ModuleElement mdle) throws DocFileIOException {
         DocPath filename = configuration.docPaths.moduleFrame(mdle);
         ModulePackageIndexFrameWriter modpackgen = new ModulePackageIndexFrameWriter(configuration, filename);
-        modpackgen.buildModulePackagesIndexFile("doclet.Window_Overview", false, mdle);
+        modpackgen.buildModulePackagesIndexFile("doclet.Window_Overview",
+                getDescription("module package index", mdle) + " (frame)",
+                false,
+                mdle);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -915,6 +915,7 @@
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
         printHtmlDocument(configuration.metakeywords.getMetaKeywordsForModule(mdle),
+                getDescription("declaration", mdle),
                 true, contentTree);
     }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -89,7 +89,7 @@
 
     /**
      * Generate a package summary page for the left-hand bottom frame. Construct
-     * the PackageFrameWriter object and then uses it generate the file.
+     * the PackageFrameWriter object and then use it generate the file.
      *
      * @param configuration the current configuration of the doclet.
      * @param packageElement The package for which "pacakge-frame.html" is to be generated.
@@ -111,7 +111,10 @@
         htmlTree.addContent(div);
         body.addContent(htmlTree);
         packgen.printHtmlDocument(
-                configuration.metakeywords.getMetaKeywords(packageElement), false, body);
+                configuration.metakeywords.getMetaKeywords(packageElement),
+                getDescription("package summary (frame)", packageElement),
+                false,
+                body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexFrameWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -31,7 +31,6 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
-import jdk.javadoc.internal.doclets.formats.html.markup.Links;
 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
 import jdk.javadoc.internal.doclets.toolkit.Content;
@@ -70,7 +69,9 @@
     public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
         DocPath filename = DocPaths.OVERVIEW_FRAME;
         PackageIndexFrameWriter packgen = new PackageIndexFrameWriter(configuration, filename);
-        packgen.buildPackageIndexFile("doclet.Window_Overview", false);
+        packgen.buildPackageIndexFile("doclet.Window_Overview",
+                "package index (frame)",
+                false);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -78,7 +78,7 @@
     public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
         DocPath filename = DocPaths.overviewSummary(configuration.frames);
         PackageIndexWriter packgen = new PackageIndexWriter(configuration, filename);
-        packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", true);
+        packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", "package index", true);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -121,7 +121,7 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         body.addContent(footer);
-        printHtmlDocument(null, true, body);
+        printHtmlDocument(null, getDescription("tree", packageElement), true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -141,7 +141,10 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         body.addContent(footer);
-        printHtmlDocument(null, true, body);
+        printHtmlDocument(null,
+                getDescription("use", packageElement),
+                true,
+                body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -316,7 +316,10 @@
      */
     @Override
     public void printDocument(Content contentTree) throws DocFileIOException {
+        String description = getDescription("declaration", packageElement);
         printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
-                true, contentTree);
+                description,
+                true,
+                contentTree);
     }
 }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -255,7 +255,7 @@
      */
     @Override
     public void printDocument(Content serializedTree) throws DocFileIOException {
-        printHtmlDocument(null, true, serializedTree);
+        printHtmlDocument(null, "serialized forms", true, serializedTree);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SingleIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -121,7 +121,7 @@
         addBottom(htmlTree);
         body.addContent(htmlTree);
         createSearchIndexFiles();
-        printHtmlDocument(null, true, body);
+        printHtmlDocument(null, "index", true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, 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
@@ -196,7 +196,7 @@
             addBlankLines(pre);
             Content div = HtmlTree.DIV(HtmlStyle.sourceContainer, pre);
             body.addContent(HtmlTree.MAIN(div));
-            writeToFile(body, outputdir.resolve(configuration.docPaths.forClass(te)));
+            writeToFile(body, outputdir.resolve(configuration.docPaths.forClass(te)), te);
         } catch (IOException e) {
             String message = resources.getText("doclet.exception.read.file", fo.getName());
             throw new SimpleDocletException(message, e);
@@ -209,11 +209,13 @@
      * @param body the documentation content to be written to the file.
      * @param path the path for the file.
      */
-    private void writeToFile(Content body, DocPath path) throws DocFileIOException {
+    private void writeToFile(Content body, DocPath path, TypeElement te) throws DocFileIOException {
         Head head = new Head(path, configuration.docletVersion)
 //                .setTimestamp(!configuration.notimestamp) // temporary: compatibility!
                 .setTitle(resources.getText("doclet.Window_Source_title"))
 //                .setCharset(configuration.charset) // temporary: compatibility!
+                .setDescription(HtmlDocletWriter.getDescription("source", te))
+                .setGenerator(HtmlDocletWriter.getGenerator(getClass()))
                 .addDefaultScript(false)
                 .setStylesheets(configuration.getMainStylesheet(), configuration.getAdditionalStylesheets());
         Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SplitIndexWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -144,7 +144,8 @@
         footer.addContent(navBar.getContent(false));
         addBottom(footer);
         body.addContent(footer);
-        printHtmlDocument(null, true, body);
+        String description = "index: " + unicode;
+        printHtmlDocument(null, description, true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -127,7 +127,7 @@
         htmlTree.addContent(navBar.getContent(false));
         addBottom(htmlTree);
         body.addContent(htmlTree);
-        printHtmlDocument(null, true, body);
+        printHtmlDocument(null, "class tree", true, body);
     }
 
     /**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Thu Feb 21 01:06:53 2019 +0100
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java	Wed Feb 20 16:15:02 2019 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -56,6 +56,8 @@
     private String title;
     private String charset;
     private final List<String> keywords;
+    private String description;
+    private String generator;
     private boolean showTimestamp;
     private boolean useModuleDirectories;
     private DocFile mainStylesheetFile;
@@ -111,6 +113,22 @@
     }
 
     /**
+     * Sets the content for the description META element.
+     */
+    public Head setDescription(String description) {
+        this.description = description;
+        return this;
+    }
+
+    /**
+     * Sets the content for the generator META element.
+     */
+    public Head setGenerator(String generator) {
+        this.generator = generator;
+        return this;
+    }
+
+    /**
      * Adds a list of keywords to appear in META [@code keywords} elements.
      *
      * @param keywords the list of keywords, or null if none need to be added
@@ -245,6 +263,14 @@
             tree.addContent(HtmlTree.META("dc.created", dateFormat.format(now)));
         }
 
+        if (description != null) {
+            tree.addContent(HtmlTree.META("description", description));
+        }
+
+        if (generator != null) {
+            tree.addContent(HtmlTree.META("generator", generator));
+        }
+
         for (String k : keywords) {
             tree.addContent(HtmlTree.META("keywords", k));
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testMetadata/TestMetadata.java	Wed Feb 20 16:15:02 2019 -0800
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8218998
+ * @summary Add metadata to generated API documentation files
+ * @library /tools/lib ../../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.javadoc/jdk.javadoc.internal.api
+ *          jdk.javadoc/jdk.javadoc.internal.tool
+ * @build toolbox.ToolBox toolbox.JavacTask javadoc.tester.*
+ * @run main TestMetadata
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import toolbox.ModuleBuilder;
+import toolbox.ToolBox;
+
+import javadoc.tester.JavadocTester;
+
+public class TestMetadata extends JavadocTester {
+    public static void main(String... args) throws Exception {
+        TestMetadata tester = new TestMetadata();
+        tester.runTests();
+    }
+
+    enum Frames { NO_FRAMES, FRAMES };
+    enum Index  { SINGLE, SPLIT };
+    enum Source { PACKAGES, MODULES };
+
+    final ToolBox tb = new ToolBox();
+    final Set<String> allGeneratorsFound = new HashSet<>();
+
+    public void runTests() throws Exception {
+        for (Source s : Source.values()) {
+            Path src = genSource(s);
+            for (Frames f : Frames.values()) {
+                 for (Index i : Index.values()) {
+                     List<String> args = new ArrayList<>();
+                     args.add("-d");
+                     args.add(String.format("out-%s-%s-%s", s, f, i));
+                     args.add("-use");
+                     if (s != Source.MODULES) {
+                         args.add("-linksource"); // broken, with modules: JDK-8219060
+                     }
+                     args.add(f == Frames.NO_FRAMES ? "--no-frames" : "--frames");
+                     if (i == Index.SPLIT) {
+                         args.add("-splitIndex");
+                     }
+                     if (s == Source.PACKAGES) {
+                         args.add("-sourcepath");
+                         args.add(src.toString());
+                         args.add("pA");
+                         args.add("pB");
+                     } else {
+                         args.add("--module-source-path");
+                         args.add(src.toString());
+                         args.add("--module");
+                         args.add("mA,mB");
+                     }
+                     javadoc(args.toArray(new String[args.size()]));
+                     checkExit(Exit.OK);
+                     checkMetadata();
+
+                     // spot check the descriptions for declarations
+                     switch (s) {
+                         case PACKAGES:
+                             checkOutput("pA/package-summary.html", true,
+                                     "<meta name=\"description\" content=\"declaration: package: pA\">");
+                             checkOutput("pA/CA.html", true,
+                                     "<meta name=\"description\" content=\"declaration: package: pA, class: CA\">");
+                             break;
+
+                         case MODULES:
+                             checkOutput("mA/module-summary.html", true,
+                                     "<meta name=\"description\" content=\"declaration: module: mA\">");
+                             checkOutput("mA/pA/package-summary.html", true,
+                                     "<meta name=\"description\" content=\"declaration: module: mA, package: pA\">");
+                             checkOutput("mA/pA/CA.html", true,
+                                     "<meta name=\"description\" content=\"declaration: module: mA, package: pA, class: CA\">");
+                             break;
+                     }
+                 }
+            }
+        }
+
+        checking ("all generators");
+        if (allGeneratorsFound.equals(allGenerators)) {
+            passed("all generators found");
+        } else {
+            Set<String> notFound = new TreeSet<>(allGenerators);
+            notFound.removeAll(allGeneratorsFound);
+            failed("not found: " + notFound);
+        }
+
+        printSummary();
+    }
+
+    final Pattern nl = Pattern.compile("[\\r\\n]+");
+    final Pattern contentPattern = Pattern.compile("content=\"([^\"]+)\">");
+    final Pattern generatorPattern = Pattern.compile("content=\"javadoc/([^\"]+)\">");
+    final Set<String> allGenerators = Set.of(
+            "AllClassesFrameWriter",
+            "AllClassesIndexWriter",
+            "AllPackagesIndexWriter",
+            "AnnotationTypeWriterImpl",
+            "ClassUseWriter",
+            "ClassWriterImpl",
+            "ConstantsSummaryWriterImpl",
+            "DeprecatedListWriter",
+            "DocFileWriter",
+            "FrameOutputWriter",
+            "HelpWriter",
+            "IndexRedirectWriter",
+            "ModuleFrameWriter",
+            "ModuleIndexFrameWriter",
+            "ModuleIndexWriter",
+            "ModulePackageIndexFrameWriter",
+            "ModuleWriterImpl",
+            "PackageFrameWriter",
+            "PackageIndexFrameWriter",
+            "PackageIndexWriter",
+            "PackageTreeWriter",
+            "PackageUseWriter",
+            "PackageWriterImpl",
+            "SerializedFormWriterImpl",
+            "SingleIndexWriter",
+            "SourceToHTMLConverter",
+            "SplitIndexWriter",
+            "TreeWriter"
+            );
+
+    void checkMetadata() throws IOException {
+        Path outputDirPath = outputDir.toPath();
+        for (Path p : tb.findFiles(".html", outputDirPath)) {
+            checkMetadata(outputDirPath.relativize(p));
+        }
+    }
+
+    void checkMetadata(Path p) {
+        checking("Check generator: " + p);
+
+        List<String> generators = nl.splitAsStream(readOutputFile(p.toString()))
+                .filter(s -> s.contains("<meta name=\"generator\""))
+                .collect(Collectors.toList());
+
+        String generator;
+        switch (generators.size()) {
+            case 0:
+                 failed("Not found: <meta name=\"generator\"");
+                 return;
+            case 1:
+                 generator = generators.get(0);
+                 break;
+            default:
+                 failed("Multiple found: <meta name=\"generator\"");
+                 return;
+        }
+
+        Matcher m = generatorPattern.matcher(generator);
+        if (m.find()) {
+            String content = m.group(1);
+            if (allGenerators.contains(content)) {
+                passed("found: " + content);
+                allGeneratorsFound.add(content);
+                checkDescription(p, content);
+            } else {
+                failed("Unrecognized content: " + content);
+            }
+        } else {
+            failed("Unrecognized line:\n" + generator);
+        }
+
+    }
+
+    void checkDescription(Path p, String generator) {
+        checking("Check description: " + p);
+
+        List<String> descriptions = nl.splitAsStream(readOutputFile(p.toString()))
+                .filter(s -> s.contains("<meta name=\"description\""))
+                .collect(Collectors.toList());
+
+        String description;
+        switch (descriptions.size()) {
+            case 0:
+                if (generator.equals("DocFileWriter")) {
+                    passed("Not found, as expected");
+                } else {
+                    failed("Not found: <meta name=\"description\"");
+                }
+                return;
+            case 1:
+                description = descriptions.get(0);
+                break;
+            default:
+                failed("Multiple found: <meta name=\"description\"");
+                return;
+        }
+
+        String content;
+        Matcher m = contentPattern.matcher(description);
+        if (m.find()) {
+            content = m.group(1);
+        } else {
+            failed("Unrecognized line:\n" + description);
+            return;
+        }
+
+        switch (generator) {
+            case "AllClassesFrameWriter":
+            case "FrameOutputWriter":
+            case "ModuleFrameWriter":
+            case "ModuleIndexFrameWriter":
+            case "ModulePackageIndexFrameWriter":
+            case "PackageFrameWriter":
+            case "PackageIndexFrameWriter":
+                check(generator, content, content.contains("frame"));
+                break;
+
+            case "AllClassesIndexWriter":
+            case "AllPackagesIndexWriter":
+            case "ModuleIndexWriter":
+            case "PackageIndexWriter":
+                check(generator, content, content.contains("index"));
+                break;
+
+
+            case "AnnotationTypeWriterImpl":
+            case "ClassWriterImpl":
+            case "ModuleWriterImpl":
+            case "PackageWriterImpl":
+                check(generator, content, content.startsWith("declaration: "));
+                break;
+
+            case "ClassUseWriter":
+            case "PackageUseWriter":
+                check(generator, content, content.startsWith("use: "));
+                break;
+
+            case "ConstantsSummaryWriterImpl":
+                check(generator, content, content.contains("constants"));
+                break;
+
+            case "DeprecatedListWriter":
+                check(generator, content, content.contains("deprecated"));
+                break;
+
+            case "DocFileWriter":
+                passed("no constraint for user-provided doc-files");
+                break;
+
+            case "HelpWriter":
+                check(generator, content, content.contains("help"));
+                break;
+
+            case "IndexRedirectWriter":
+                check(generator, content, content.contains("redirect"));
+                break;
+
+            case "PackageTreeWriter":
+            case "TreeWriter":
+                check(generator, content, content.contains("tree"));
+                break;
+
+            case "SerializedFormWriterImpl":
+                check(generator, content, content.contains("serialized"));
+                break;
+
+            case "SingleIndexWriter":
+            case "SplitIndexWriter":
+                check(generator, content, content.startsWith("index"));
+                break;
+
+            case "SourceToHTMLConverter":
+                check(generator, content, content.startsWith("source:"));
+                break;
+
+            default:
+                failed("unexpected generator: " + generator);
+                break;
+        }
+    }
+
+    void check(String generator, String content, boolean ok) {
+        if (ok) {
+            passed("OK: " + generator + " " + content);
+        } else {
+            failed("unexpected value for " + generator + ": " + content);
+        }
+    }
+
+    Path genSource(Source s) throws IOException {
+        Path src = Path.of("src-" + s);
+        switch (s) {
+            case PACKAGES:
+                tb.writeJavaFiles(src,
+                    "/** Package pA. */ package pA;",
+                    "/** Class pA.CA. */ package pA; public class CA { }",
+                    "/** Anno pA.Anno, */ package pA; public @interface Anno { }",
+                    "/** Serializable pA.Ser, */ package pA; public class Ser implements java.io.Serializable { }",
+                    "/** Package pB. */ package pB;",
+                    "/** Class pB.CB. */ package pB; public class CB { }");
+                tb.writeFile(src.resolve("pA").resolve("doc-files").resolve("extra.html"),
+                        "<!doctype html>\n<html><head></head><body>Extra</body></html>");
+                break;
+
+            case MODULES:
+                new ModuleBuilder(tb, "mA")
+                        .exports("pA")
+                        .classes("/** Package mA/pA. */ package pA;")
+                        .classes("/** Class mA/pA.CA. */ package pA; public class CA { }")
+                        .write(src);
+                new ModuleBuilder(tb, "mB")
+                        .exports("pB")
+                        .classes("/** Package mB/pB. */ package pB;")
+                        .classes("/** Class mB/pB.CB. */ package pB; public class CB { }")
+                        .write(src);
+                break;
+        }
+
+        return src;
+    }
+}
+