8218998: Add metadata to generated API documentation files

Reviewed-by: hannesw
This commit is contained in:
Jonathan Gibbons 2019-02-20 16:15:02 -08:00
parent b578cf83c9
commit 431b49663a
33 changed files with 565 additions and 82 deletions

View file

@ -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 java.util.SortedMap;
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 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
* 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 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
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 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
* 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 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
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);
}
/**

View file

@ -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 java.util.*;
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 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
* 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 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
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);
}
/**

View file

@ -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 @@ package jdk.javadoc.internal.doclets.formats.html;
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 @@ public class AllClassesFrameWriter extends HtmlDocletWriter {
HtmlTree div = HtmlTree.DIV(HtmlStyle.indexContainer, ul);
htmlTree.addContent(div);
body.addContent(htmlTree);
printHtmlDocument(null, false, body);
printHtmlDocument(null, "all classes (frame)", false, body);
}
/**

View file

@ -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 @@ public class AllClassesIndexWriter extends HtmlDocletWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
bodyTree.addContent(footer);
printHtmlDocument(null, true, bodyTree);
printHtmlDocument(null, "class index", true, bodyTree);
}
/**

View file

@ -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 @@ public class AllPackagesIndexWriter extends HtmlDocletWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
bodyTree.addContent(footer);
printHtmlDocument(null, true, bodyTree);
printHtmlDocument(null, "package index", true, bodyTree);
}
/**

View file

@ -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 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
*/
@Override
public void printDocument(Content contentTree) throws DocFileIOException {
String description = getDescription("declaration", annotationType);
printHtmlDocument(configuration.metakeywords.getMetaKeywords(annotationType),
true, contentTree);
description,
true,
contentTree);
}
/**

View file

@ -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 @@ package jdk.javadoc.internal.doclets.formats.html;
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 @@ public class ClassUseWriter extends SubWriterHolderWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
body.addContent(footer);
printHtmlDocument(null, true, body);
String description = getDescription("use", typeElement);
printHtmlDocument(null, description, true, body);
}
/**

View file

@ -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 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
*/
@Override
public void printDocument(Content contentTree) throws DocFileIOException {
String description = getDescription("declaration", typeElement);
printHtmlDocument(configuration.metakeywords.getMetaKeywords(typeElement),
true, contentTree);
description,
true,
contentTree);
}
/**

View file

@ -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 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
*/
@Override
public void printDocument(Content contentTree) throws DocFileIOException {
printHtmlDocument(null, true, contentTree);
printHtmlDocument(null, "summary of constants", true, contentTree);
}
}

View file

@ -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 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
htmlTree.addContent(navBar.getContent(false));
addBottom(htmlTree);
body.addContent(htmlTree);
printHtmlDocument(null, true, body);
String description = "deprecated elements";
printHtmlDocument(null, description, true, body);
}
/**

View file

@ -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 @@ public class DocFilesHandlerImpl implements DocFilesHandler {
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);
}

View file

@ -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 @@ public class FrameOutputWriter extends HtmlDocletWriter {
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)

View file

@ -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 @@ public class HelpWriter extends HtmlDocletWriter {
htmlTree.addContent(navBar.getContent(false));
addBottom(htmlTree);
body.addContent(htmlTree);
printHtmlDocument(null, true, body);
printHtmlDocument(null, "help", true, body);
}
/**

View file

@ -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.ExecutableElement;
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 @@ public class HtmlDocletWriter {
* @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 @@ public class HtmlDocletWriter {
* @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);
@ -2110,6 +2122,55 @@ public class HtmlDocletWriter {
return new TableHeader(contents.packageLabel, contents.descriptionLabel);
}
/**
* 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.
*

View file

@ -79,6 +79,8 @@ public class IndexRedirectWriter extends HtmlDocletWriter {
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);

View file

@ -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.HtmlConstants;
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 @@ public class ModuleFrameWriter extends HtmlDocletWriter {
htmlTree.addContent(div);
body.addContent(htmlTree);
mdlgen.printHtmlDocument(
configuration.metakeywords.getMetaKeywordsForModule(moduleElement), false, body);
configuration.metakeywords.getMetaKeywordsForModule(moduleElement),
"module summary (frame)",
false,
body);
}
/**

View file

@ -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 class ModuleIndexFrameWriter extends AbstractModuleIndexWriter {
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);
}
/**

View file

@ -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 class ModuleIndexWriter extends AbstractModuleIndexWriter {
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);
}
/**

View file

@ -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 class ModulePackageIndexFrameWriter extends AbstractModuleIndexWriter {
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);
}
/**

View file

@ -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 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
@Override
public void printDocument(Content contentTree) throws DocFileIOException {
printHtmlDocument(configuration.metakeywords.getMetaKeywordsForModule(mdle),
getDescription("declaration", mdle),
true, contentTree);
}

View file

@ -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 @@ public class PackageFrameWriter extends HtmlDocletWriter {
/**
* 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 @@ public class PackageFrameWriter extends HtmlDocletWriter {
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);
}
/**

View file

@ -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.HtmlConstants;
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 class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
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);
}
/**

View file

@ -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 class PackageIndexWriter extends AbstractPackageIndexWriter {
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);
}
/**

View file

@ -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 @@ public class PackageTreeWriter extends AbstractTreeWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
body.addContent(footer);
printHtmlDocument(null, true, body);
printHtmlDocument(null, getDescription("tree", packageElement), true, body);
}
/**

View file

@ -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 @@ public class PackageUseWriter extends SubWriterHolderWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
body.addContent(footer);
printHtmlDocument(null, true, body);
printHtmlDocument(null,
getDescription("use", packageElement),
true,
body);
}
/**

View file

@ -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 @@ public class PackageWriterImpl extends HtmlDocletWriter
*/
@Override
public void printDocument(Content contentTree) throws DocFileIOException {
String description = getDescription("declaration", packageElement);
printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
true, contentTree);
description,
true,
contentTree);
}
}

View file

@ -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 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
*/
@Override
public void printDocument(Content serializedTree) throws DocFileIOException {
printHtmlDocument(null, true, serializedTree);
printHtmlDocument(null, "serialized forms", true, serializedTree);
}
/**

View file

@ -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 @@ public class SingleIndexWriter extends AbstractIndexWriter {
addBottom(htmlTree);
body.addContent(htmlTree);
createSearchIndexFiles();
printHtmlDocument(null, true, body);
printHtmlDocument(null, "index", true, body);
}
/**

View file

@ -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 @@ public class SourceToHTMLConverter {
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 @@ public class SourceToHTMLConverter {
* @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(),

View file

@ -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 @@ public class SplitIndexWriter extends AbstractIndexWriter {
footer.addContent(navBar.getContent(false));
addBottom(footer);
body.addContent(footer);
printHtmlDocument(null, true, body);
String description = "index: " + unicode;
printHtmlDocument(null, description, true, body);
}
/**

View file

@ -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 @@ public class TreeWriter extends AbstractTreeWriter {
htmlTree.addContent(navBar.getContent(false));
addBottom(htmlTree);
body.addContent(htmlTree);
printHtmlDocument(null, true, body);
printHtmlDocument(null, "class tree", true, body);
}
/**

View file

@ -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 @@ public class Head {
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;
@ -110,6 +112,22 @@ public class Head {
return this;
}
/**
* 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.
*
@ -245,6 +263,14 @@ public class Head {
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));
}

View file

@ -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;
}
}