8180717: Upgrade the docs bundle index page

Reviewed-by: jjg, ihse
This commit is contained in:
Mandy Chung 2017-05-22 11:08:26 -07:00
parent 92ce207628
commit 20eec3c5a8
3 changed files with 249 additions and 122 deletions

View File

@ -31,18 +31,23 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder; import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
/** /**
* Build tool to generate the docs bundle index page. * Build tool to generate the docs bundle index page.
@ -104,60 +109,34 @@ public class GenDocsBundlePage {
} }
private static final String HEADER_TITLE = "@HEADER_TITLE@"; private static final String HEADER_TITLE = "@HEADER_TITLE@";
final Path outputfile; final Path outputfile;
final String title; final String title;
final Map<String, String> moduleGroups; final Map<String, Set<ModuleDescriptor>> moduleGroups = new HashMap<>();
GenDocsBundlePage(String title, Path outputfile) throws IOException GenDocsBundlePage(String title, Path outputfile) throws IOException
{ {
this.outputfile = outputfile; this.outputfile = outputfile;
this.title = title; this.title = title;
this.moduleGroups = moduleGroups();
}
static Map<String, String> moduleGroups() throws IOException { // read module groups
ModuleFinder finder = ModuleFinder.ofSystem(); ModuleFinder finder = ModuleFinder.ofSystem();
Map<String, String> groups = new HashMap<>();
try (InputStream in = GenDocsBundlePage.class.getResourceAsStream(MODULE_GROUPS_PROPS)) { try (InputStream in = GenDocsBundlePage.class.getResourceAsStream(MODULE_GROUPS_PROPS)) {
Properties props = new Properties(); Properties props = new Properties();
props.load(in); props.load(in);
for (String key: props.stringPropertyNames()) { for (String key: props.stringPropertyNames()) {
Set<String> mods = Stream.of(props.getProperty(key).split("\\s+")) Set<ModuleDescriptor> mods =
.filter(mn -> finder.find(mn).isPresent()) Stream.of(props.getProperty(key).split("\\s+"))
.map(String::trim) .map(String::trim)
.collect(Collectors.toSet()); .flatMap(mn -> finder.find(mn).stream())
.map(ModuleReference::descriptor)
.collect(toSet());
// divide into 3 columns: Java SE, JDK, JavaFX
StringBuilder sb = new StringBuilder();
sb.append(mods.stream()
.filter(mn -> mn.startsWith("java."))
.sorted()
.map(GenDocsBundlePage::toHRef)
.collect(Collectors.joining("\n")));
sb.append("</td>\n<td>")
.append(mods.stream()
.filter(mn -> mn.startsWith("jdk."))
.sorted()
.map(GenDocsBundlePage::toHRef)
.collect(Collectors.joining("\n")));
sb.append("</td>\n<td>");
if (mods.stream().anyMatch(mn -> mn.startsWith("javafx."))) {
sb.append(mods.stream()
.filter(mn -> mn.startsWith("javafx."))
.sorted()
.map(GenDocsBundlePage::toHRef)
.collect(Collectors.joining("\n")));
}
String name = "@" + key.toUpperCase(Locale.ENGLISH) + "@"; String name = "@" + key.toUpperCase(Locale.ENGLISH) + "@";
groups.put(name, sb.toString()); moduleGroups.put(name, mods);
};
} }
} }
return groups;
}
static String toHRef(String mn) {
return String.format("<a href=\"api/%s-summary.html\">%s</a><br>", mn, mn);
}
void run(BufferedReader reader) throws IOException { void run(BufferedReader reader) throws IOException {
if (Files.notExists(outputfile.getParent())) { if (Files.notExists(outputfile.getParent())) {
@ -174,13 +153,95 @@ public class GenDocsBundlePage {
if (line.contains(HEADER_TITLE)) { if (line.contains(HEADER_TITLE)) {
line = line.replace(HEADER_TITLE, title); line = line.replace(HEADER_TITLE, title);
} }
if (line.contains("@")) { int i = line.indexOf('@');
for (Map.Entry<String,String> e: moduleGroups.entrySet()) { int j = line.indexOf('@', i+1);
if (line.contains(e.getKey())) { if (i >= 0 && i < j) {
line = line.replace(e.getKey(), e.getValue()); String name = line.substring(i, j+1);
} if (moduleGroups.containsKey(name)) {
line = line.replace(name, formatModuleGroup(name));
} }
} }
return line; return line;
} }
String toHRef(ModuleDescriptor md) {
String mn = md.name();
String formattedName;
if (hasExportedAPIs(md)) {
// has exported APIs
formattedName = mn;
} else if (!md.provides().isEmpty()) {
// a provider
formattedName = "<i>" + mn + "</i>";
} else {
// a tool
formattedName = "<i>" + mn + "</i>";
}
return String.format("<a href=\"api/%s-summary.html\">%s</a>",
mn, formattedName);
}
String formatModuleGroup(String groupName) {
StringBuilder sb = new StringBuilder();
// organize in Java SE, JDK, JavaFX, JCP groups
Set<ModuleDescriptor> modules = moduleGroups.get(groupName);
Arrays.stream(ModuleGroup.values())
.forEach(g -> {
Set<ModuleDescriptor> mods = modules.stream()
.filter(md -> g.predicate.test(md.name()))
.collect(toSet());
if (!mods.isEmpty()) {
sb.append("<div class=" + g.cssClass + ">\n");
// modules with exported API
mods.stream()
.filter(this::hasExportedAPIs)
.sorted(Comparator.comparing(ModuleDescriptor::name))
.map(this::toHRef)
.forEach(m -> sb.append(m).append("\n"));
// tools and providers
mods.stream()
.filter(md -> !hasExportedAPIs(md))
.sorted(Comparator.comparing(ModuleDescriptor::name))
.map(this::toHRef)
.forEach(m -> sb.append(m).append("\n"));
sb.append("</div>");
}
});
return sb.toString();
}
private boolean hasExportedAPIs(ModuleDescriptor md) {
if (md.exports().stream().anyMatch(e -> !e.isQualified())) {
return true;
}
// this should check if any indirect exports
// checking requires transitive would be sufficient for JDK modules
if (md.requires().stream()
.map(ModuleDescriptor.Requires::modifiers)
.anyMatch(mods -> mods.contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE))) {
return true;
}
return false;
}
private static final Set<String> NON_JAVA_SE_MODULES =
Set.of("java.jnlp", "java.smartcardio");
/**
* CSS class names are defined in docs-bundle-page.html
*/
enum ModuleGroup {
JAVA_SE("javase", mn -> mn.startsWith("java.") && !NON_JAVA_SE_MODULES.contains(mn)),
JDK("jdk", mn -> mn.startsWith("jdk.")),
JAVAFX("javafx", mn -> mn.startsWith("javafx.")),
NON_JAVA_SE("jcp", NON_JAVA_SE_MODULES::contains);
final String cssClass;
final Predicate<String> predicate;
ModuleGroup(String cssClass, Predicate<String> predicate) {
this.cssClass = cssClass;
this.predicate = predicate;
}
}
} }

View File

@ -26,47 +26,76 @@ questions.
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>@HEADER_TITLE@</title>
<meta http-equiv="content-type" content="text/html;" charset="utf-8"> <meta http-equiv="content-type" content="text/html;" charset="utf-8">
<link rel="stylesheet" href="resources/jdk-default.css" type="text/css" /> <link rel="stylesheet" href="resources/jdk-default.css" type="text/css" />
<style type="text/css"> <style type="text/css">
table a { text-decoration: none }
table { border: none }
th, td { border: 2px solid white; }
thead th { background-color: #DDD }
tbody th { background-color: #EEE }
table div.javase, ul.key span.javase { background-color: #C6E7F3 }
table div.jdk, ul.key span.jdk { background-color: #ECE1C5 }
table div.javafx, ul.key span.javafx { background-color: #ECEDCC }
table div.jcp, ul.key span.jcp { background-color: #E9E9E9 }
td div { padding: 3px 5px; color: blue }
table tbody td div a { padding: 0 .5em; margin: 0: 1em; }
table tbody td div a:link { color: black }
table tbody td div a:visited { color: black }
table tbody td div a[href]:hover { color: black; text-decoration: underline }
td { padding: 0 }
table tbody td div a { padding: 0 .5em; margin: 0: 1em }
.key { font-size: smaller; }
ul.key li { display:inline-block; padding: 0 1em }
ul.key span {
border: 1px solid black;
font-family: DejaVu Sans Mono, monospace;
}
ul.key span:before { content: " " }
ul.key span:after { content: " " }
caption { caption {
text-align: center; text-align: center;
} }
tr:nth-child(even), tr:nth-child(even) th[scope=row] {
background-color: #EEE;
}
tr:nth-child(odd), tr:nth-child(odd) th[scope=row] {
background-color: #EEE;
}
</style> </style>
<title>@HEADER_TITLE@</title>
</head> </head>
<body>
<h1>@HEADER_TITLE@</h1> <h1>@HEADER_TITLE@</h1>
<ul> <ul>
<li><a href="api/index.html">JDK API Specification</a></li> <li><a href="api/index.html">JDK API Specification</a></li>
<li>Java Language Specification</li> <li><a href="https://docs.oracle.com/javase/specs/">
<li>Java Virtual Machine Specification</li> Java Language and Virtual Machine Specifications</a></li>
<li><a href="https://www.oracle.com/pls/topic/lookup?ctx=javase9&id=tools_reference_overview">
Tools Reference</a></li>
</ul> </ul>
<table> <table>
<caption>Modules</caption> <caption style="display:none">JDK Modules</caption>
<thead> <thead>
<tr> <tr>
<th scope="col">Group</th> <th scope="col">Group</th>
<th scope="col">Java SE</th> <th scope="col">Modules</th>
<th scope="col">JDK</th>
<th scope="col">JavaFX</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th scope="row">Foundation</th> <th scope="row">Foundation</th>
<td>@CORE_MODULES@</td> <td>@JAVA_BASE@</td>
</tr>
<tr>
<th scope="row">Security</th>
<td>@SECURITY_MODULES@</td>
</tr>
<tr>
<th scope="row">Instrumentation and<br>Management</th>
<td>@INSTRUMENT_MGMT_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Integration</th> <th scope="row">Integration</th>
@ -74,43 +103,69 @@ questions.
</tr> </tr>
<tr> <tr>
<th scope="row">User Interface</th> <th scope="row">User Interface</th>
<td>@UI_TOOLKITS_MODULES@</td> <td>@UI_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Compiler and Scripting</th> <th scope="row">Compilation</th>
<td>@COMPILER_SCRIPTING_MODULES@</td> <td>@COMPILER_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Debugging</th> <th scope="row">Scripting</th>
<td>@DEBUG_MODULES@</td> <td>@SCRIPTING_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Tools and Tool APIs</th> <th scope="row">Security</th>
<td>@TOOL_MODULES@</td> <td>@SECURITY_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="row">Incubating Features</th> <th scope="row">Management</th>
<td>@MANAGEMENT_MODULES@</td>
</tr>
<tr>
<th scope="row">Instrumentation</th>
<td>@INSTRUMENT_MODULES@</td>
</tr>
<tr>
<th scope="row">Serviceability</th>
<td>@SVC_MODULES@</td>
</tr>
<tr>
<th scope="row">Packaging</th>
<td>@PACKAGING_MODULES@</td>
</tr>
<tr>
<th scope="row">Incubator</th>
<td>@INCUBATOR_MODULES@</td> <td>@INCUBATOR_MODULES@</td>
</tr> </tr>
<tr>
<th scope="row">Non-Java SE</th>
<td>@OTHER_MODULES@</td>
</tr>
<tr> <tr>
<th scope="row">Java EE</th> <th scope="row">Java EE</th>
<td>@JAVA_EE_MODULES@</td> <td>@JAVA_EE_MODULES@</td>
</tr> </tr>
<tr> <tr>
<th scope="col"></th> <th scope="row">Aggregator</th>
<th scope="col">Outside Java SE</th> <td>@AGGREGATOR_MODULES@</td>
<th scope="col">JDK</th>
<th scope="col">JavaFX</th>
</tr>
<tr>
<th scope="row">Others</th>
<td>@OTHER_MODULES@</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p class="key">Key:
<ul class="key">
<li><span class="javase">&nbsp;</span>&nbsp; Java SE
<li><span class="jdk">&nbsp;</span>&nbsp; JDK
<li><span class="javafx">&nbsp;</span>&nbsp; JavaFX
<li><span class="jcp">&nbsp;</span>&nbsp; Non-Java SE
<li><i>italic</i> No Exported API (e.g. a tool or provider)</li>
</ul>
<p> <p>
<hr/> <hr>
<a href="legal/cpyr.html">Copyright</a>&copy; 1993, 2017, Oracle and/or its affiliates. All rights reserved.</p> <a href="legal/cpyr.html">Copyright</a> &copy 1993, 2017, Oracle and/or its affiliates. All rights reserved.</p>
</body> </body>
</html> </html>

View File

@ -1,13 +1,8 @@
# Module Grouping for the docs bundle page # Module Grouping for the docs bundle page
# #
core_modules=\ java_base=\
java.base \ java.base
jdk.charsets \
jdk.localedata \
jdk.net \
jdk.sctp \
jdk.zipfs
java_ee_modules=\ java_ee_modules=\
java.activation \ java.activation \
@ -17,6 +12,10 @@ java.xml.bind \
java.xml.ws \ java.xml.ws \
java.xml.ws.annotation java.xml.ws.annotation
aggregator_modules=\
java.se \
java.se.ee
security_modules=\ security_modules=\
java.security.jgss \ java.security.jgss \
java.security.sasl \ java.security.sasl \
@ -26,18 +25,22 @@ jdk.security.jgss \
jdk.crypto.cryptoki \ jdk.crypto.cryptoki \
jdk.crypto.ec \ jdk.crypto.ec \
jdk.crypto.mscapi \ jdk.crypto.mscapi \
jdk.crypto.ucrypto jdk.crypto.ucrypto \
jdk.policytool
instrument_mgmt_modules=\ instrument_modules=\
java.instrument \ java.instrument
management_modules=\
java.management \ java.management \
java.management.rmi \ java.management.rmi \
jdk.jfr \
jdk.management \ jdk.management \
jdk.management.agent \ jdk.management.agent \
jdk.management.cmm \ jdk.management.cmm \
jdk.management.jfr \ jdk.management.jfr \
jdk.management.resource \ jdk.management.resource \
jdk.snmp \
jdk.jconsole
integration_modules=\ integration_modules=\
java.logging \ java.logging \
@ -47,11 +50,18 @@ java.rmi \
java.sql \ java.sql \
java.sql.rowset \ java.sql.rowset \
java.xml \ java.xml \
jdk.charsets \
jdk.localedata \
jdk.net \
jdk.sctp \
jdk.jsobject \
jdk.httpserver \ jdk.httpserver \
jdk.naming.dns \ jdk.naming.dns \
jdk.naming.rmi jdk.naming.rmi \
jdk.xml.dom \
jdk.zipfs
ui_toolkits_modules=\ ui_modules=\
java.datatransfer \ java.datatransfer \
java.desktop \ java.desktop \
javafx.base \ javafx.base \
@ -63,39 +73,40 @@ javafx.swing \
javafx.web \ javafx.web \
jdk.accessibility jdk.accessibility
other_modules=\ svc_modules=\
java.jnlp \ jdk.jfr \
java.smartcardio \
jdk.jsobject \
jdk.xml.dom
debug_modules=\
jdk.jdi \
jdk.jdwp.agent
tool_modules=\
jdk.attach \ jdk.attach \
jdk.editpad \
jdk.jartool \
jdk.javadoc \
jdk.jcmd \ jdk.jcmd \
jdk.jconsole \ jdk.jdi \
jdk.jdeps \ jdk.jdwp.agent \
jdk.jlink \
jdk.jshell \
jdk.jstatd \ jdk.jstatd \
jdk.hotspot.agent
packaging_modules=\
jdk.jartool \
jdk.jlink \
jdk.pack \ jdk.pack \
jdk.policytool \ jdk.packager.services
jdk.packager.services \
compiler_modules=\
java.compiler \
jdk.compiler \
jdk.javadoc \
jdk.jdeps \
jdk.editpad \
jdk.jshell \
jdk.rmic jdk.rmic
compiler_scripting_modules=\ scripting_modules=\
java.compiler \
java.scripting \ java.scripting \
jdk.compiler \
jdk.dynalink \ jdk.dynalink \
jdk.scripting.nashorn \ jdk.scripting.nashorn \
jdk.scripting.nashorn.shell jdk.scripting.nashorn.shell
other_modules=\
java.jnlp \
java.smartcardio
incubator_modules=\ incubator_modules=\
jdk.incubator.httpclient jdk.incubator.httpclient